blob: ebf6e9e2711f7f1e2fb88ad04f027e21cbe6ec56 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
24#include "media/engine/fakewebrtcvoiceengine.h"
25#include "media/engine/webrtcvoiceengine.h"
26#include "modules/audio_device/include/mock_audio_device.h"
27#include "modules/audio_processing/include/mock_audio_processing.h"
28#include "pc/channel.h"
29#include "rtc_base/arraysize.h"
30#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010031#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/scoped_ref_ptr.h"
33#include "test/field_trial.h"
34#include "test/gtest.h"
35#include "test/mock_audio_decoder_factory.h"
36#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
46
solenberg418b7d32017-06-13 00:38:27 -070047constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070048
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
50const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070051const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
53const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
55const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080056const cricket::AudioCodec
57 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
58const cricket::AudioCodec
59 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
60
solenberg2100c0b2017-03-01 11:29:29 -080061const uint32_t kSsrc0 = 0;
62const uint32_t kSsrc1 = 1;
63const uint32_t kSsrcX = 0x99;
64const uint32_t kSsrcY = 0x17;
65const uint32_t kSsrcZ = 0x42;
66const uint32_t kSsrcW = 0x02;
67const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
solenberg971cab02016-06-14 10:02:41 -070069constexpr int kRtpHistoryMs = 5000;
70
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010071constexpr webrtc::GainControl::Mode kDefaultAgcMode =
72#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
73 webrtc::GainControl::kFixedDigital;
74#else
75 webrtc::GainControl::kAdaptiveAnalog;
76#endif
77
78constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
79 webrtc::NoiseSuppression::kHigh;
80
solenberg9a5f032222017-03-15 06:14:12 -070081void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
82 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010083
84 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010085 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010086 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010087 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070088#if defined(WEBRTC_WIN)
89 EXPECT_CALL(*adm, SetPlayoutDevice(
90 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
91 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
92 .WillOnce(Return(0));
93#else
94 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
95#endif // #if defined(WEBRTC_WIN)
96 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
97 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
98 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +010099#if defined(WEBRTC_WIN)
100 EXPECT_CALL(*adm, SetRecordingDevice(
101 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
102 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
103 .WillOnce(Return(0));
104#else
105 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
106#endif // #if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
108 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
109 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700110 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
111 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113
114 // Teardown.
115 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
116 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
118 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100119 EXPECT_CALL(*adm, Release()).Times(3)
120 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700121}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200122} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123
solenbergff976312016-03-30 23:28:51 -0700124// Tests that our stub library "works".
125TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700126 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700127 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700128 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
129 new rtc::RefCountedObject<
130 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700131 webrtc::AudioProcessing::Config apm_config;
132 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
133 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700134 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700135 EXPECT_CALL(*apm, DetachAecDump());
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100136 cricket::FakeWebRtcVoiceEngine voe;
solenbergff976312016-03-30 23:28:51 -0700137 EXPECT_FALSE(voe.IsInited());
138 {
ossuc54071d2016-08-17 02:45:41 -0700139 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700140 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700141 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100142 new cricket::VoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700143 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700144 EXPECT_TRUE(voe.IsInited());
145 }
146 EXPECT_FALSE(voe.IsInited());
147}
148
deadbeef884f5852016-01-15 09:20:04 -0800149class FakeAudioSink : public webrtc::AudioSinkInterface {
150 public:
151 void OnData(const Data& audio) override {}
152};
153
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800154class FakeAudioSource : public cricket::AudioSource {
155 void SetSink(Sink* sink) override {}
156};
157
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158class WebRtcVoiceEngineTestFake : public testing::Test {
159 public:
stefanba4c0e42016-02-04 04:12:24 -0800160 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
161
162 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700163 : apm_(new rtc::RefCountedObject<
164 StrictMock<webrtc::test::MockAudioProcessing>>()),
165 apm_gc_(*apm_->gain_control()),
166 apm_ec_(*apm_->echo_cancellation()),
167 apm_ns_(*apm_->noise_suppression()),
168 apm_vd_(*apm_->voice_detection()),
169 call_(webrtc::Call::Config(&event_log_)),
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100170 voe_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700171 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800172 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700173 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800174 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700175 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
176 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700177 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700178 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800179 // Default Options.
180 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
181 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100182 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
183 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800184 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100185 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
186 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800189 // Init does not overwrite default AGC config.
190 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
191 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
192 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
194 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700195 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800196 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700197 // factories. Those tests should probably be moved elsewhere.
198 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
199 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100200 engine_.reset(new cricket::WebRtcVoiceEngine(
201 &adm_, encoder_factory, decoder_factory, nullptr, apm_,
202 new cricket::VoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700203 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200204 send_parameters_.codecs.push_back(kPcmuCodec);
205 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100206
solenberg76377c52017-02-21 00:54:31 -0800207 // Default Options.
208 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 }
solenberg8189b022016-06-14 12:13:00 -0700210
solenbergff976312016-03-30 23:28:51 -0700211 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700212 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700213 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
214 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200215 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000216 }
solenberg8189b022016-06-14 12:13:00 -0700217
solenbergff976312016-03-30 23:28:51 -0700218 bool SetupRecvStream() {
219 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700220 return false;
221 }
solenberg2100c0b2017-03-01 11:29:29 -0800222 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700223 }
solenberg8189b022016-06-14 12:13:00 -0700224
solenbergff976312016-03-30 23:28:51 -0700225 bool SetupSendStream() {
226 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000227 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 }
solenberg2100c0b2017-03-01 11:29:29 -0800229 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800230 return false;
231 }
peaha9cc40b2017-06-29 08:32:09 -0700232 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800233 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
solenberg8189b022016-06-14 12:13:00 -0700235
236 bool AddRecvStream(uint32_t ssrc) {
237 EXPECT_TRUE(channel_);
238 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
239 }
240
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000241 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700242 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700243 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800244 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
245 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700246 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800247 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000248 }
solenberg8189b022016-06-14 12:13:00 -0700249
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700251 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000252 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 }
solenberg8189b022016-06-14 12:13:00 -0700254
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200255 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 }
258
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100259 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
260 const auto* send_stream = call_.GetAudioSendStream(ssrc);
261 EXPECT_TRUE(send_stream);
262 return *send_stream;
263 }
264
deadbeef884f5852016-01-15 09:20:04 -0800265 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
266 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
267 EXPECT_TRUE(recv_stream);
268 return *recv_stream;
269 }
270
solenberg3a941542015-11-16 07:34:50 -0800271 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800272 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800273 }
274
solenberg7add0582015-11-20 09:59:34 -0800275 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800276 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800277 }
278
solenberg059fb442016-10-26 05:12:24 -0700279 void SetSend(bool enable) {
280 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700281 if (enable) {
282 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
283 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
284 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700285 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700286 }
solenberg059fb442016-10-26 05:12:24 -0700287 channel_->SetSend(enable);
288 }
289
290 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700291 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700292 ASSERT_TRUE(channel_);
293 EXPECT_TRUE(channel_->SetSendParameters(params));
294 }
295
minyue6b825df2016-10-31 04:08:32 -0700296 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
297 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700298 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700299 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700300 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700301 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700302 }
303 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700304 }
305
solenbergffbbcac2016-11-17 05:25:37 -0800306 void TestInsertDtmf(uint32_t ssrc, bool caller,
307 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700308 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000309 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700310 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000311 // send stream.
312 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800313 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700317 SetSendParameters(send_parameters_);
318 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800320 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800321 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700322 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324
325 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700326 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800327 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800329 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330 }
331
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100335 // Test send.
336 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800337 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100338 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800340 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800341 EXPECT_EQ(codec.id, telephone_event.payload_type);
342 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100343 EXPECT_EQ(2, telephone_event.event_code);
344 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 }
346
347 // Test that send bandwidth is set correctly.
348 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000349 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
350 // |expected_result| is the expected result from SetMaxSendBandwidth().
351 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700352 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
353 int max_bitrate,
354 bool expected_result,
355 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200356 cricket::AudioSendParameters parameters;
357 parameters.codecs.push_back(codec);
358 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700359 if (expected_result) {
360 SetSendParameters(parameters);
361 } else {
362 EXPECT_FALSE(channel_->SetSendParameters(parameters));
363 }
solenberg2100c0b2017-03-01 11:29:29 -0800364 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 }
366
skvlade0d46372016-04-07 22:59:22 -0700367 // Sets the per-stream maximum bitrate limit for the specified SSRC.
368 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700369 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700370 EXPECT_EQ(1UL, parameters.encodings.size());
371
Oskar Sundbom78807582017-11-16 11:09:55 +0100372 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700373 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700374 }
375
solenberg059fb442016-10-26 05:12:24 -0700376 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700377 cricket::AudioSendParameters send_parameters;
378 send_parameters.codecs.push_back(codec);
379 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700380 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700381 }
382
ossu20a4b3f2017-04-27 02:08:52 -0700383 void CheckSendCodecBitrate(int32_t ssrc,
384 const char expected_name[],
385 int expected_bitrate) {
386 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
387 EXPECT_EQ(expected_name, spec->format.name);
388 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700389 }
390
ossu20a4b3f2017-04-27 02:08:52 -0700391 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
392 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
minyue6b825df2016-10-31 04:08:32 -0700395 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
396 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
397 }
398
skvlade0d46372016-04-07 22:59:22 -0700399 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
400 int global_max,
401 int stream_max,
402 bool expected_result,
403 int expected_codec_bitrate) {
404 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800405 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700406
407 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700408 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800409 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700410
411 // Verify that reading back the parameters gives results
412 // consistent with the Set() result.
413 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800414 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700415 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
416 EXPECT_EQ(expected_result ? stream_max : -1,
417 resulting_parameters.encodings[0].max_bitrate_bps);
418
419 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800420 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700421 }
422
stefan13f1a0a2016-11-30 07:22:58 -0800423 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
424 int expected_min_bitrate_bps,
425 const char* start_bitrate_kbps,
426 int expected_start_bitrate_bps,
427 const char* max_bitrate_kbps,
428 int expected_max_bitrate_bps) {
429 EXPECT_TRUE(SetupSendStream());
430 auto& codecs = send_parameters_.codecs;
431 codecs.clear();
432 codecs.push_back(kOpusCodec);
433 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
436 SetSendParameters(send_parameters_);
437
438 EXPECT_EQ(expected_min_bitrate_bps,
439 call_.GetConfig().bitrate_config.min_bitrate_bps);
440 EXPECT_EQ(expected_start_bitrate_bps,
441 call_.GetConfig().bitrate_config.start_bitrate_bps);
442 EXPECT_EQ(expected_max_bitrate_bps,
443 call_.GetConfig().bitrate_config.max_bitrate_bps);
444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100536 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100541 stats.apm_statistics.delay_median_ms = 234;
542 stats.apm_statistics.delay_standard_deviation_ms = 567;
543 stats.apm_statistics.echo_return_loss = 890;
544 stats.apm_statistics.echo_return_loss_enhancement = 1234;
545 stats.apm_statistics.residual_echo_likelihood = 0.432f;
546 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100547 stats.ana_statistics.bitrate_action_counter = 321;
548 stats.ana_statistics.channel_action_counter = 432;
549 stats.ana_statistics.dtx_action_counter = 543;
550 stats.ana_statistics.fec_action_counter = 654;
551 stats.ana_statistics.frame_length_increase_counter = 765;
552 stats.ana_statistics.frame_length_decrease_counter = 876;
553 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700554 stats.typing_noise_detected = true;
555 return stats;
556 }
557 void SetAudioSendStreamStats() {
558 for (auto* s : call_.GetAudioSendStreams()) {
559 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200560 }
solenberg85a04962015-10-27 03:35:21 -0700561 }
solenberg566ef242015-11-06 15:34:49 -0800562 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
563 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700564 const auto stats = GetAudioSendStreamStats();
565 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
566 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
567 EXPECT_EQ(info.packets_sent, stats.packets_sent);
568 EXPECT_EQ(info.packets_lost, stats.packets_lost);
569 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
570 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800571 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700572 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
573 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
574 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
575 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100576 EXPECT_EQ(info.apm_statistics.delay_median_ms,
577 stats.apm_statistics.delay_median_ms);
578 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
579 stats.apm_statistics.delay_standard_deviation_ms);
580 EXPECT_EQ(info.apm_statistics.echo_return_loss,
581 stats.apm_statistics.echo_return_loss);
582 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
583 stats.apm_statistics.echo_return_loss_enhancement);
584 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
585 stats.apm_statistics.residual_echo_likelihood);
586 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
587 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700588 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
589 stats.ana_statistics.bitrate_action_counter);
590 EXPECT_EQ(info.ana_statistics.channel_action_counter,
591 stats.ana_statistics.channel_action_counter);
592 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
593 stats.ana_statistics.dtx_action_counter);
594 EXPECT_EQ(info.ana_statistics.fec_action_counter,
595 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700596 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
597 stats.ana_statistics.frame_length_increase_counter);
598 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
599 stats.ana_statistics.frame_length_decrease_counter);
600 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
601 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800602 EXPECT_EQ(info.typing_noise_detected,
603 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700604 }
605
606 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
607 webrtc::AudioReceiveStream::Stats stats;
608 stats.remote_ssrc = 123;
609 stats.bytes_rcvd = 456;
610 stats.packets_rcvd = 768;
611 stats.packets_lost = 101;
612 stats.fraction_lost = 23.45f;
613 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100614 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700615 stats.ext_seqnum = 678;
616 stats.jitter_ms = 901;
617 stats.jitter_buffer_ms = 234;
618 stats.jitter_buffer_preferred_ms = 567;
619 stats.delay_estimate_ms = 890;
620 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700621 stats.total_samples_received = 5678901;
622 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200623 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200624 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700625 stats.expand_rate = 5.67f;
626 stats.speech_expand_rate = 8.90f;
627 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200628 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700629 stats.accelerate_rate = 4.56f;
630 stats.preemptive_expand_rate = 7.89f;
631 stats.decoding_calls_to_silence_generator = 12;
632 stats.decoding_calls_to_neteq = 345;
633 stats.decoding_normal = 67890;
634 stats.decoding_plc = 1234;
635 stats.decoding_cng = 5678;
636 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700637 stats.decoding_muted_output = 3456;
638 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 return stats;
640 }
641 void SetAudioReceiveStreamStats() {
642 for (auto* s : call_.GetAudioReceiveStreams()) {
643 s->SetStats(GetAudioReceiveStreamStats());
644 }
645 }
646 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700647 const auto stats = GetAudioReceiveStreamStats();
648 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
649 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
650 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
651 EXPECT_EQ(info.packets_lost, stats.packets_lost);
652 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
653 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800654 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700655 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
656 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
657 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200658 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700659 stats.jitter_buffer_preferred_ms);
660 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
661 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700662 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
663 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200664 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200665 EXPECT_EQ(info.jitter_buffer_delay_seconds,
666 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700667 EXPECT_EQ(info.expand_rate, stats.expand_rate);
668 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
669 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200670 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700671 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
672 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200673 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700674 stats.decoding_calls_to_silence_generator);
675 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
676 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
677 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
678 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
679 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700680 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700681 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200682 }
hbos1acfbd22016-11-17 23:43:29 -0800683 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
684 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
685 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
686 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
687 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
688 codec.ToCodecParameters());
689 }
690 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
691 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
692 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
693 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
694 codec.ToCodecParameters());
695 }
696 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200697
peah8271d042016-11-22 07:24:52 -0800698 bool IsHighPassFilterEnabled() {
699 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
700 }
701
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700703 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700704 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800705 webrtc::test::MockGainControl& apm_gc_;
706 webrtc::test::MockEchoCancellation& apm_ec_;
707 webrtc::test::MockNoiseSuppression& apm_ns_;
708 webrtc::test::MockVoiceDetection& apm_vd_;
skvlad11a9cbf2016-10-07 11:53:05 -0700709 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200710 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700712 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700713 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200714 cricket::AudioSendParameters send_parameters_;
715 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800716 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700717 webrtc::AudioProcessing::Config apm_config_;
718
stefanba4c0e42016-02-04 04:12:24 -0800719 private:
720 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721};
722
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723// Tests that we can create and destroy a channel.
724TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700725 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726}
727
solenberg31fec402016-05-06 02:13:12 -0700728// Test that we can add a send stream and that it has the correct defaults.
729TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
730 EXPECT_TRUE(SetupChannel());
731 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800732 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
733 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
734 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700735 EXPECT_EQ("", config.rtp.c_name);
736 EXPECT_EQ(0u, config.rtp.extensions.size());
737 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
738 config.send_transport);
739}
740
741// Test that we can add a receive stream and that it has the correct defaults.
742TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
743 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800744 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700745 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800746 GetRecvStreamConfig(kSsrcX);
747 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700748 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
749 EXPECT_FALSE(config.rtp.transport_cc);
750 EXPECT_EQ(0u, config.rtp.extensions.size());
751 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
752 config.rtcp_send_transport);
753 EXPECT_EQ("", config.sync_group);
754}
755
stefanba4c0e42016-02-04 04:12:24 -0800756TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700757 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800758 bool opus_found = false;
759 for (cricket::AudioCodec codec : codecs) {
760 if (codec.name == "opus") {
761 EXPECT_TRUE(HasTransportCc(codec));
762 opus_found = true;
763 }
764 }
765 EXPECT_TRUE(opus_found);
766}
767
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768// Test that we set our inbound codecs properly, including changing PT.
769TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700770 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200771 cricket::AudioRecvParameters parameters;
772 parameters.codecs.push_back(kIsacCodec);
773 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800774 parameters.codecs.push_back(kTelephoneEventCodec1);
775 parameters.codecs.push_back(kTelephoneEventCodec2);
776 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 parameters.codecs[2].id = 126;
778 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800779 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700780 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
781 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
782 {{0, {"PCMU", 8000, 1}},
783 {106, {"ISAC", 16000, 1}},
784 {126, {"telephone-event", 8000, 1}},
785 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
788// Test that we fail to set an unknown inbound codec.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700793 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
797// Test that we fail if we have duplicate types in the inbound list.
798TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700799 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200800 cricket::AudioRecvParameters parameters;
801 parameters.codecs.push_back(kIsacCodec);
802 parameters.codecs.push_back(kCn16000Codec);
803 parameters.codecs[1].id = kIsacCodec.id;
804 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805}
806
807// Test that we can decode OPUS without stereo parameters.
808TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700809 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 cricket::AudioRecvParameters parameters;
811 parameters.codecs.push_back(kIsacCodec);
812 parameters.codecs.push_back(kPcmuCodec);
813 parameters.codecs.push_back(kOpusCodec);
814 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800815 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700816 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
817 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
818 {{0, {"PCMU", 8000, 1}},
819 {103, {"ISAC", 16000, 1}},
820 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821}
822
823// Test that we can decode OPUS with stereo = 0.
824TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700825 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 cricket::AudioRecvParameters parameters;
827 parameters.codecs.push_back(kIsacCodec);
828 parameters.codecs.push_back(kPcmuCodec);
829 parameters.codecs.push_back(kOpusCodec);
830 parameters.codecs[2].params["stereo"] = "0";
831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800832 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700833 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
834 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
835 {{0, {"PCMU", 8000, 1}},
836 {103, {"ISAC", 16000, 1}},
837 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
840// Test that we can decode OPUS with stereo = 1.
841TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700842 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200843 cricket::AudioRecvParameters parameters;
844 parameters.codecs.push_back(kIsacCodec);
845 parameters.codecs.push_back(kPcmuCodec);
846 parameters.codecs.push_back(kOpusCodec);
847 parameters.codecs[2].params["stereo"] = "1";
848 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800849 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700850 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
851 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
852 {{0, {"PCMU", 8000, 1}},
853 {103, {"ISAC", 16000, 1}},
854 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855}
856
857// Test that changes to recv codecs are applied to all streams.
858TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700859 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200860 cricket::AudioRecvParameters parameters;
861 parameters.codecs.push_back(kIsacCodec);
862 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800863 parameters.codecs.push_back(kTelephoneEventCodec1);
864 parameters.codecs.push_back(kTelephoneEventCodec2);
865 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200866 parameters.codecs[2].id = 126;
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700868 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
869 EXPECT_TRUE(AddRecvStream(ssrc));
870 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
871 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
872 {{0, {"PCMU", 8000, 1}},
873 {106, {"ISAC", 16000, 1}},
874 {126, {"telephone-event", 8000, 1}},
875 {107, {"telephone-event", 32000, 1}}})));
876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877}
878
879TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700880 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 cricket::AudioRecvParameters parameters;
882 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885
solenberg2100c0b2017-03-01 11:29:29 -0800886 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800887 ASSERT_EQ(1, dm.count(106));
888 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889}
890
891// Test that we can apply the same set of codecs again while playing.
892TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700893 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 cricket::AudioRecvParameters parameters;
895 parameters.codecs.push_back(kIsacCodec);
896 parameters.codecs.push_back(kCn16000Codec);
897 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700898 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
deadbeefcb383672017-04-26 16:28:42 -0700901 // Remapping a payload type to a different codec should fail.
902 parameters.codecs[0] = kOpusCodec;
903 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800905 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906}
907
908// Test that we can add a codec while playing.
909TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700910 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 cricket::AudioRecvParameters parameters;
912 parameters.codecs.push_back(kIsacCodec);
913 parameters.codecs.push_back(kCn16000Codec);
914 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700915 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 parameters.codecs.push_back(kOpusCodec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800919 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
deadbeefcb383672017-04-26 16:28:42 -0700922// Test that we accept adding the same codec with a different payload type.
923// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
924TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
925 EXPECT_TRUE(SetupRecvStream());
926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
929
930 ++parameters.codecs[0].id;
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932}
933
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000937 // Test that when autobw is enabled, bitrate is kept as the default
938 // value. autobw is enabled for the following tests because the target
939 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
941 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700942 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
ossu20a4b3f2017-04-27 02:08:52 -0700947 // opus, default bitrate == 32000 in mono.
948 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700955 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
956 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700957 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
961 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
962 // Rates above the max (510000) should be capped.
963 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700967 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000968
969 // Test that we can only set a maximum bitrate for a fixed-rate codec
970 // if it's bigger than the fixed rate.
971
972 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700973 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980}
981
982TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700983 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200984 const int kDesiredBitrate = 128000;
985 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700986 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700988 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000989
990 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800991 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
solenberg2100c0b2017-03-01 11:29:29 -0800993 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000994}
995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996// Test that bitrate cannot be set for CBR codecs.
997// Bitrate is ignored if it is higher than the fixed bitrate.
998// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001000 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001003 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001004 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001005
1006 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009
1010 send_parameters_.max_bandwidth_bps = 128;
1011 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013}
1014
skvlade0d46372016-04-07 22:59:22 -07001015// Test that the per-stream bitrate limit and the global
1016// bitrate limit both apply.
1017TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1018 EXPECT_TRUE(SetupSendStream());
1019
ossu20a4b3f2017-04-27 02:08:52 -07001020 // opus, default bitrate == 32000.
1021 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001022 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1023 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1024 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1025
1026 // CBR codecs allow both maximums to exceed the bitrate.
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1029 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1030 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1031
1032 // CBR codecs don't allow per stream maximums to be too low.
1033 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1035}
1036
1037// Test that an attempt to set RtpParameters for a stream that does not exist
1038// fails.
1039TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1040 EXPECT_TRUE(SetupChannel());
1041 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001042 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001043 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1044
1045 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001047}
1048
1049TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001050 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001051 // This test verifies that setting RtpParameters succeeds only if
1052 // the structure contains exactly one encoding.
1053 // TODO(skvlad): Update this test when we start supporting setting parameters
1054 // for each encoding individually.
1055
1056 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001057 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001058 // Two or more encodings should result in failure.
1059 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001060 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001061 // Zero encodings should also fail.
1062 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001064}
1065
1066// Changing the SSRC through RtpParameters is not allowed.
1067TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1068 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001069 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001070 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001072}
1073
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001076TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001079 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082 ASSERT_EQ(1u, parameters.encodings.size());
1083 ASSERT_TRUE(parameters.encodings[0].active);
1084 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087
1088 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001089 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001090 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001091 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
solenberg2100c0b2017-03-01 11:29:29 -08001092 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1093 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094}
1095
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001096// Test that SetRtpSendParameters configures the correct encoding channel for
1097// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001098TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1099 SetupForMultiSendStream();
1100 // Create send streams.
1101 for (uint32_t ssrc : kSsrcs4) {
1102 EXPECT_TRUE(
1103 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1104 }
1105 // Configure one stream to be limited by the stream config, another to be
1106 // limited by the global max, and the third one with no per-stream limit
1107 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001108 SetGlobalMaxBitrate(kOpusCodec, 32000);
1109 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1110 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001111 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1112
ossu20a4b3f2017-04-27 02:08:52 -07001113 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1114 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1115 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001116
1117 // Remove the global cap; the streams should switch to their respective
1118 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001119 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001120 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1121 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1122 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001123}
1124
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001125// Test that GetRtpSendParameters returns the currently configured codecs.
1126TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001127 EXPECT_TRUE(SetupSendStream());
1128 cricket::AudioSendParameters parameters;
1129 parameters.codecs.push_back(kIsacCodec);
1130 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001131 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001134 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001135 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1136 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137}
1138
deadbeefcb443432016-12-12 11:12:36 -08001139// Test that GetRtpSendParameters returns an SSRC.
1140TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1141 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001142 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001143 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001144 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001145}
1146
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001148TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149 EXPECT_TRUE(SetupSendStream());
1150 cricket::AudioSendParameters parameters;
1151 parameters.codecs.push_back(kIsacCodec);
1152 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001153 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
solenberg2100c0b2017-03-01 11:29:29 -08001155 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156
1157 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001158 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001159
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001161 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1162 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001163}
1164
minyuececec102017-03-27 13:04:25 -07001165// Test that max_bitrate_bps in send stream config gets updated correctly when
1166// SetRtpSendParameters is called.
1167TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1168 webrtc::test::ScopedFieldTrials override_field_trials(
1169 "WebRTC-Audio-SendSideBwe/Enabled/");
1170 EXPECT_TRUE(SetupSendStream());
1171 cricket::AudioSendParameters send_parameters;
1172 send_parameters.codecs.push_back(kOpusCodec);
1173 SetSendParameters(send_parameters);
1174
1175 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1176 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1177 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1178
1179 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001180 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001181 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1182
1183 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1184 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1185}
1186
Seth Hampson24722b32017-12-22 09:36:42 -08001187// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1188// a value <= 0, setting the parameters returns false.
1189TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1190 EXPECT_TRUE(SetupSendStream());
1191 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1192 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1193 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1194 rtp_parameters.encodings[0].bitrate_priority);
1195
1196 rtp_parameters.encodings[0].bitrate_priority = 0;
1197 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1198 rtp_parameters.encodings[0].bitrate_priority = -1.0;
1199 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1200}
1201
1202// Test that the bitrate_priority in the send stream config gets updated when
1203// SetRtpSendParameters is set for the VoiceMediaChannel.
1204TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1205 EXPECT_TRUE(SetupSendStream());
1206 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1207
1208 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1209 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1210 rtp_parameters.encodings[0].bitrate_priority);
1211 double new_bitrate_priority = 2.0;
1212 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
1213 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1214
1215 // The priority should get set for both the audio channel's rtp parameters
1216 // and the audio send stream's audio config.
1217 EXPECT_EQ(
1218 new_bitrate_priority,
1219 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1220 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1221}
1222
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223// Test that GetRtpReceiveParameters returns the currently configured codecs.
1224TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1225 EXPECT_TRUE(SetupRecvStream());
1226 cricket::AudioRecvParameters parameters;
1227 parameters.codecs.push_back(kIsacCodec);
1228 parameters.codecs.push_back(kPcmuCodec);
1229 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1230
1231 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001232 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001233 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1234 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1235 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1236}
1237
deadbeefcb443432016-12-12 11:12:36 -08001238// Test that GetRtpReceiveParameters returns an SSRC.
1239TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1240 EXPECT_TRUE(SetupRecvStream());
1241 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001242 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001243 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001244 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001245}
1246
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001247// Test that if we set/get parameters multiple times, we get the same results.
1248TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1249 EXPECT_TRUE(SetupRecvStream());
1250 cricket::AudioRecvParameters parameters;
1251 parameters.codecs.push_back(kIsacCodec);
1252 parameters.codecs.push_back(kPcmuCodec);
1253 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1254
1255 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001256 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001257
1258 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001259 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001260
1261 // ... And this shouldn't change the params returned by
1262 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001263 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1264 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001265}
1266
deadbeef3bc15102017-04-20 19:25:07 -07001267// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1268// aren't signaled. It should return an empty "RtpEncodingParameters" when
1269// configured to receive an unsignaled stream and no packets have been received
1270// yet, and start returning the SSRC once a packet has been received.
1271TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1272 ASSERT_TRUE(SetupChannel());
1273 // Call necessary methods to configure receiving a default stream as
1274 // soon as it arrives.
1275 cricket::AudioRecvParameters parameters;
1276 parameters.codecs.push_back(kIsacCodec);
1277 parameters.codecs.push_back(kPcmuCodec);
1278 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1279
1280 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1281 // stream. Should return nothing.
1282 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1283
1284 // Set a sink for an unsignaled stream.
1285 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1286 // Value of "0" means "unsignaled stream".
1287 channel_->SetRawAudioSink(0, std::move(fake_sink));
1288
1289 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1290 // in this method means "unsignaled stream".
1291 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1292 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1293 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1294
1295 // Receive PCMU packet (SSRC=1).
1296 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1297
1298 // The |ssrc| member should still be unset.
1299 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1300 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1301 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1302}
1303
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001304// Test that we apply codecs properly.
1305TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001306 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 cricket::AudioSendParameters parameters;
1308 parameters.codecs.push_back(kIsacCodec);
1309 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001310 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001312 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001313 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001314 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1315 EXPECT_EQ(96, send_codec_spec.payload_type);
1316 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1317 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1318 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001319 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001320 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
ossu20a4b3f2017-04-27 02:08:52 -07001323// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1324// AudioSendStream.
1325TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001326 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kIsacCodec);
1329 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001330 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001331 parameters.codecs[0].id = 96;
1332 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001333 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001334 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001335 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001336 // Calling SetSendCodec again with same codec which is already set.
1337 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001338 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001339 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001340}
1341
ossu20a4b3f2017-04-27 02:08:52 -07001342// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1343// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001344
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001345// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
1351 parameters.codecs[0].clockrate = 50000;
1352 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001353}
1354
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001355// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001357 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001358 cricket::AudioSendParameters parameters;
1359 parameters.codecs.push_back(kOpusCodec);
1360 parameters.codecs[0].bitrate = 0;
1361 parameters.codecs[0].channels = 0;
1362 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001363}
1364
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001365// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001367 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001368 cricket::AudioSendParameters parameters;
1369 parameters.codecs.push_back(kOpusCodec);
1370 parameters.codecs[0].bitrate = 0;
1371 parameters.codecs[0].channels = 0;
1372 parameters.codecs[0].params["stereo"] = "1";
1373 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374}
1375
1376// Test that if channel is 1 for opus and there's no stereo, we fail.
1377TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001378 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001379 cricket::AudioSendParameters parameters;
1380 parameters.codecs.push_back(kOpusCodec);
1381 parameters.codecs[0].bitrate = 0;
1382 parameters.codecs[0].channels = 1;
1383 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384}
1385
1386// Test that if channel is 1 for opus and stereo=0, we fail.
1387TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kOpusCodec);
1391 parameters.codecs[0].bitrate = 0;
1392 parameters.codecs[0].channels = 1;
1393 parameters.codecs[0].params["stereo"] = "0";
1394 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
1397// Test that if channel is 1 for opus and stereo=1, we fail.
1398TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001399 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 cricket::AudioSendParameters parameters;
1401 parameters.codecs.push_back(kOpusCodec);
1402 parameters.codecs[0].bitrate = 0;
1403 parameters.codecs[0].channels = 1;
1404 parameters.codecs[0].params["stereo"] = "1";
1405 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406}
1407
ossu20a4b3f2017-04-27 02:08:52 -07001408// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001410 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 cricket::AudioSendParameters parameters;
1412 parameters.codecs.push_back(kOpusCodec);
1413 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001414 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001415 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416}
1417
ossu20a4b3f2017-04-27 02:08:52 -07001418// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 0;
1424 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001427}
1428
ossu20a4b3f2017-04-27 02:08:52 -07001429// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001430TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001431 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 cricket::AudioSendParameters parameters;
1433 parameters.codecs.push_back(kOpusCodec);
1434 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001435 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001437 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001438 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001439
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001441 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001442 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001443}
1444
ossu20a4b3f2017-04-27 02:08:52 -07001445// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 cricket::AudioSendParameters parameters;
1449 parameters.codecs.push_back(kOpusCodec);
1450 parameters.codecs[0].bitrate = 0;
1451 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001452 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001453 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454}
1455
ossu20a4b3f2017-04-27 02:08:52 -07001456// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001458 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 cricket::AudioSendParameters parameters;
1460 parameters.codecs.push_back(kOpusCodec);
1461 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001462 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001464 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001465 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001466
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001468 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001469 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001470}
1471
ossu20a4b3f2017-04-27 02:08:52 -07001472// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001474 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001475 cricket::AudioSendParameters parameters;
1476 parameters.codecs.push_back(kOpusCodec);
1477 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001478 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001479 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1480 EXPECT_EQ(111, spec.payload_type);
1481 EXPECT_EQ(96000, spec.target_bitrate_bps);
1482 EXPECT_EQ("opus", spec.format.name);
1483 EXPECT_EQ(2, spec.format.num_channels);
1484 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485}
1486
ossu20a4b3f2017-04-27 02:08:52 -07001487// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001489 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001490 cricket::AudioSendParameters parameters;
1491 parameters.codecs.push_back(kOpusCodec);
1492 parameters.codecs[0].bitrate = 30000;
1493 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001494 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001495 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001496}
1497
ossu20a4b3f2017-04-27 02:08:52 -07001498// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001500 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001501 cricket::AudioSendParameters parameters;
1502 parameters.codecs.push_back(kOpusCodec);
1503 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001504 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001505 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001506}
1507
ossu20a4b3f2017-04-27 02:08:52 -07001508// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 cricket::AudioSendParameters parameters;
1512 parameters.codecs.push_back(kOpusCodec);
1513 parameters.codecs[0].bitrate = 30000;
1514 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001515 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001516 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001517}
1518
stefan13f1a0a2016-11-30 07:22:58 -08001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1520 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1521 200000);
1522}
1523
1524TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1525 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1526}
1527
1528TEST_F(WebRtcVoiceEngineTestFake,
1529 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1530 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1531}
1532
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1534 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1535}
1536
1537TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001538 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001539 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1540 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001541 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001542 SetSendParameters(send_parameters_);
1543 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1544 << "Setting max bitrate should keep previous min bitrate.";
1545 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1546 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001547 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001548}
1549
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001550// Test that we can enable NACK with opus as caller.
1551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].AddFeedbackParam(
1556 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1557 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001558 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001559 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001560 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561}
1562
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001563// Test that we can enable NACK with opus as callee.
1564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001565 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].AddFeedbackParam(
1569 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1570 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001573 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001575
1576 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001577 cricket::StreamParams::CreateLegacy(kSsrcX)));
1578 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001579}
1580
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581// Test that we can enable NACK on receive streams.
1582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001583 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001584 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].AddFeedbackParam(
1588 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1589 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1591 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001593 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1594 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595}
1596
1597// Test that we can disable NACK.
1598TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kOpusCodec);
1602 parameters.codecs[0].AddFeedbackParam(
1603 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1604 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001606 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 parameters.codecs.clear();
1609 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001611 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
1614// Test that we can disable NACK on receive streams.
1615TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001617 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001618 cricket::AudioSendParameters parameters;
1619 parameters.codecs.push_back(kOpusCodec);
1620 parameters.codecs[0].AddFeedbackParam(
1621 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1622 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1625 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001627 parameters.codecs.clear();
1628 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001630 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1631 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632}
1633
1634// Test that NACK is enabled on a new receive stream.
1635TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001636 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001637 cricket::AudioSendParameters parameters;
1638 parameters.codecs.push_back(kIsacCodec);
1639 parameters.codecs.push_back(kCn16000Codec);
1640 parameters.codecs[0].AddFeedbackParam(
1641 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1642 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001643 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001644 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001645
solenberg2100c0b2017-03-01 11:29:29 -08001646 EXPECT_TRUE(AddRecvStream(kSsrcY));
1647 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1648 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1649 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001650}
1651
stefanba4c0e42016-02-04 04:12:24 -08001652TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001653 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001654 cricket::AudioSendParameters send_parameters;
1655 send_parameters.codecs.push_back(kOpusCodec);
1656 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001658
1659 cricket::AudioRecvParameters recv_parameters;
1660 recv_parameters.codecs.push_back(kIsacCodec);
1661 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001662 EXPECT_TRUE(AddRecvStream(kSsrcX));
1663 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001664 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001665 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001666
ossudedfd282016-06-14 07:12:39 -07001667 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001668 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001669 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001670 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001671 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001672}
1673
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001674// Test that we can switch back and forth between Opus and ISAC with CN.
1675TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001676 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001677
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters opus_parameters;
1679 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001680 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001681 {
ossu20a4b3f2017-04-27 02:08:52 -07001682 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1683 EXPECT_EQ(111, spec.payload_type);
1684 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001685 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001687 cricket::AudioSendParameters isac_parameters;
1688 isac_parameters.codecs.push_back(kIsacCodec);
1689 isac_parameters.codecs.push_back(kCn16000Codec);
1690 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(103, spec.payload_type);
1695 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001696 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001699 {
ossu20a4b3f2017-04-27 02:08:52 -07001700 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1701 EXPECT_EQ(111, spec.payload_type);
1702 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001703 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001704}
1705
1706// Test that we handle various ways of specifying bitrate.
1707TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001708 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 cricket::AudioSendParameters parameters;
1710 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001712 {
ossu20a4b3f2017-04-27 02:08:52 -07001713 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1714 EXPECT_EQ(103, spec.payload_type);
1715 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1716 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001717 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001718
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001719 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001720 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001721 {
ossu20a4b3f2017-04-27 02:08:52 -07001722 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1723 EXPECT_EQ(103, spec.payload_type);
1724 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1725 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001726 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001727 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001729 {
ossu20a4b3f2017-04-27 02:08:52 -07001730 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1731 EXPECT_EQ(103, spec.payload_type);
1732 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1733 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001734 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001738 {
ossu20a4b3f2017-04-27 02:08:52 -07001739 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1740 EXPECT_EQ(0, spec.payload_type);
1741 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1742 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001743 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001746 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001747 {
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(0, spec.payload_type);
1750 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1751 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001752 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001753
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001754 parameters.codecs[0] = kOpusCodec;
1755 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001756 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001757 {
ossu20a4b3f2017-04-27 02:08:52 -07001758 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1759 EXPECT_EQ(111, spec.payload_type);
1760 EXPECT_STREQ("opus", spec.format.name.c_str());
1761 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763}
1764
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001765// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 cricket::AudioSendParameters parameters;
1769 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001770}
1771
1772// Test that we can set send codecs even with telephone-event codec as the first
1773// one on the list.
1774TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001775 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001777 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001778 parameters.codecs.push_back(kIsacCodec);
1779 parameters.codecs.push_back(kPcmuCodec);
1780 parameters.codecs[0].id = 98; // DTMF
1781 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(96, spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001786 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001787}
1788
solenberg31642aa2016-03-14 08:00:37 -07001789// Test that payload type range is limited for telephone-event codec.
1790TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001791 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001792 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001793 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001794 parameters.codecs.push_back(kIsacCodec);
1795 parameters.codecs[0].id = 0; // DTMF
1796 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001798 EXPECT_TRUE(channel_->CanInsertDtmf());
1799 parameters.codecs[0].id = 128; // DTMF
1800 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1801 EXPECT_FALSE(channel_->CanInsertDtmf());
1802 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001804 EXPECT_TRUE(channel_->CanInsertDtmf());
1805 parameters.codecs[0].id = -1; // DTMF
1806 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1807 EXPECT_FALSE(channel_->CanInsertDtmf());
1808}
1809
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001810// Test that we can set send codecs even with CN codec as the first
1811// one on the list.
1812TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001813 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 cricket::AudioSendParameters parameters;
1815 parameters.codecs.push_back(kCn16000Codec);
1816 parameters.codecs.push_back(kIsacCodec);
1817 parameters.codecs.push_back(kPcmuCodec);
1818 parameters.codecs[0].id = 98; // wideband CN
1819 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_EQ(96, send_codec_spec.payload_type);
1823 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001824 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825}
1826
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001827// Test that we set VAD and DTMF types correctly as caller.
1828TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001829 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001830 cricket::AudioSendParameters parameters;
1831 parameters.codecs.push_back(kIsacCodec);
1832 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001833 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 parameters.codecs.push_back(kCn16000Codec);
1835 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001836 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 parameters.codecs[0].id = 96;
1838 parameters.codecs[2].id = 97; // wideband CN
1839 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001841 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1842 EXPECT_EQ(96, send_codec_spec.payload_type);
1843 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1844 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001845 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001846 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001847}
1848
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001849// Test that we set VAD and DTMF types correctly as callee.
1850TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001851 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 cricket::AudioSendParameters parameters;
1853 parameters.codecs.push_back(kIsacCodec);
1854 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001855 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001856 parameters.codecs.push_back(kCn16000Codec);
1857 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001858 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 parameters.codecs[0].id = 96;
1860 parameters.codecs[2].id = 97; // wideband CN
1861 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001863 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001864 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001865
ossu20a4b3f2017-04-27 02:08:52 -07001866 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1867 EXPECT_EQ(96, send_codec_spec.payload_type);
1868 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1869 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001870 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001871 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001872}
1873
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001874// Test that we only apply VAD if we have a CN codec that matches the
1875// send codec clockrate.
1876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001877 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001878 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001879 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 parameters.codecs.push_back(kIsacCodec);
1881 parameters.codecs.push_back(kCn16000Codec);
1882 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001884 {
ossu20a4b3f2017-04-27 02:08:52 -07001885 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1886 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1887 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001888 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001889 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001893 {
ossu20a4b3f2017-04-27 02:08:52 -07001894 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1895 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001896 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001897 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001898 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001899 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001901 {
ossu20a4b3f2017-04-27 02:08:52 -07001902 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1903 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1904 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001906 }
Brave Yao5225dd82015-03-26 07:39:19 +08001907 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001909 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001910 {
ossu20a4b3f2017-04-27 02:08:52 -07001911 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1912 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001913 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001914 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001915}
1916
1917// Test that we perform case-insensitive matching of codec names.
1918TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001919 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001920 cricket::AudioSendParameters parameters;
1921 parameters.codecs.push_back(kIsacCodec);
1922 parameters.codecs.push_back(kPcmuCodec);
1923 parameters.codecs.push_back(kCn16000Codec);
1924 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001925 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001926 parameters.codecs[0].name = "iSaC";
1927 parameters.codecs[0].id = 96;
1928 parameters.codecs[2].id = 97; // wideband CN
1929 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001930 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001931 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1932 EXPECT_EQ(96, send_codec_spec.payload_type);
1933 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1934 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001935 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001936 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937}
1938
stefanba4c0e42016-02-04 04:12:24 -08001939class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1940 public:
1941 WebRtcVoiceEngineWithSendSideBweTest()
1942 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1943};
1944
1945TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1946 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001947 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001948 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001949 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1950 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1951 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001952 extension.id);
1953 return;
1954 }
1955 }
1956 FAIL() << "Transport sequence number extension not in header-extension list.";
1957}
1958
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001959// Test support for audio level header extension.
1960TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001961 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001962}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001963TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001964 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001965}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001966
solenbergd4adce42016-11-17 06:26:52 -08001967// Test support for transport sequence number header extension.
1968TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1969 TestSetSendRtpHeaderExtensions(
1970 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001971}
solenbergd4adce42016-11-17 06:26:52 -08001972TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1973 TestSetRecvRtpHeaderExtensions(
1974 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001975}
1976
solenberg1ac56142015-10-13 03:58:19 -07001977// Test that we can create a channel and start sending on it.
1978TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001979 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001980 SetSendParameters(send_parameters_);
1981 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001983 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001984 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001985}
1986
1987// Test that a channel will send if and only if it has a source and is enabled
1988// for sending.
1989TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001990 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001992 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001993 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001994 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1995 SetAudioSend(kSsrcX, true, &fake_source_);
1996 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1997 SetAudioSend(kSsrcX, true, nullptr);
1998 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001999}
2000
solenberg94218532016-06-16 10:53:22 -07002001// Test that a channel is muted/unmuted.
2002TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2003 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2006 SetAudioSend(kSsrcX, true, nullptr);
2007 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2008 SetAudioSend(kSsrcX, false, nullptr);
2009 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002010}
2011
solenberg6d6e7c52016-04-13 09:07:30 -07002012// Test that SetSendParameters() does not alter a stream's send state.
2013TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2014 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002015 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002016
2017 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002018 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002019 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002020
2021 // Changing RTP header extensions will recreate the AudioSendStream.
2022 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002023 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002024 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002025 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002026
2027 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002028 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002029 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002030
2031 // Changing RTP header extensions will recreate the AudioSendStream.
2032 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002033 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002034 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002035}
2036
solenberg1ac56142015-10-13 03:58:19 -07002037// Test that we can create a channel and start playing out on it.
2038TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002039 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002040 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002041 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002042 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002043 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002044 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002045}
2046
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002047// Test that we can add and remove send streams.
2048TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2049 SetupForMultiSendStream();
2050
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002052 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002053
solenbergc96df772015-10-21 13:01:53 -07002054 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002055 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002056 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002057 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002059 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 }
tfarina5237aaf2015-11-10 23:44:30 -08002061 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062
solenbergc96df772015-10-21 13:01:53 -07002063 // Delete the send streams.
2064 for (uint32_t ssrc : kSsrcs4) {
2065 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002066 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002067 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068 }
solenbergc96df772015-10-21 13:01:53 -07002069 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070}
2071
2072// Test SetSendCodecs correctly configure the codecs in all send streams.
2073TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2074 SetupForMultiSendStream();
2075
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002076 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002077 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002078 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002079 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080 }
2081
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002082 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002084 parameters.codecs.push_back(kIsacCodec);
2085 parameters.codecs.push_back(kCn16000Codec);
2086 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002087 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088
2089 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002090 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002091 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2092 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002093 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2094 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2095 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002096 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 }
2098
minyue7a973442016-10-20 03:27:12 -07002099 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002100 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002101 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002102 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002103 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2104 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002105 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2106 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002107 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 }
2109}
2110
2111// Test we can SetSend on all send streams correctly.
2112TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2113 SetupForMultiSendStream();
2114
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002115 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002116 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002118 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002119 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002120 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002121 }
2122
2123 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002124 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002125 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002127 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128 }
2129
2130 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002131 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002132 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002134 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 }
2136}
2137
2138// Test we can set the correct statistics on all send streams.
2139TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2140 SetupForMultiSendStream();
2141
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002143 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002145 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 }
solenberg85a04962015-10-27 03:35:21 -07002147
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002148 // Create a receive stream to check that none of the send streams end up in
2149 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002150 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002151
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002153 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002154 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002155 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156
solenberg85a04962015-10-27 03:35:21 -07002157 // Check stats for the added streams.
2158 {
2159 cricket::VoiceMediaInfo info;
2160 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161
solenberg85a04962015-10-27 03:35:21 -07002162 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002163 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002164 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002165 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002166 }
hbos1acfbd22016-11-17 23:43:29 -08002167 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002168
2169 // We have added one receive stream. We should see empty stats.
2170 EXPECT_EQ(info.receivers.size(), 1u);
2171 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002172 }
solenberg1ac56142015-10-13 03:58:19 -07002173
solenberg2100c0b2017-03-01 11:29:29 -08002174 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002175 {
2176 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002177 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002178 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002179 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002180 EXPECT_EQ(0u, info.receivers.size());
2181 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002182
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002183 // Deliver a new packet - a default receive stream should be created and we
2184 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002185 {
2186 cricket::VoiceMediaInfo info;
2187 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2188 SetAudioReceiveStreamStats();
2189 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002190 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002191 EXPECT_EQ(1u, info.receivers.size());
2192 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002193 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002194 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195}
2196
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197// Test that we can add and remove receive streams, and do proper send/playout.
2198// We can receive on multiple streams while sending one stream.
2199TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002200 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002201
solenberg1ac56142015-10-13 03:58:19 -07002202 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002203 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002204 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002205
solenberg1ac56142015-10-13 03:58:19 -07002206 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002207 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002208 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002209 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002210
solenberg1ac56142015-10-13 03:58:19 -07002211 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002212 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002213
2214 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002215 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2216 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2217 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218
2219 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002220 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002221 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002222
2223 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002224 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2226 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002227
aleloi84ef6152016-08-04 05:28:21 -07002228 // Restart playout and make sure recv streams are played out.
2229 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002230 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2231 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002232
aleloi84ef6152016-08-04 05:28:21 -07002233 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002234 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2235 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002236}
2237
wu@webrtc.org97077a32013-10-25 21:18:33 +00002238TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002239 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002240 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2241 .Times(1)
2242 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002243 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2244 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002245 send_parameters_.options.tx_agc_target_dbov = 3;
2246 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2247 send_parameters_.options.tx_agc_limiter = true;
2248 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002249 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2250 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2251 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002252 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002253}
2254
minyue6b825df2016-10-31 04:08:32 -07002255TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2256 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002257 send_parameters_.options.audio_network_adaptor = true;
2258 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002259 SetSendParameters(send_parameters_);
2260 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002261 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002262}
2263
2264TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2265 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002266 send_parameters_.options.audio_network_adaptor = true;
2267 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002268 SetSendParameters(send_parameters_);
2269 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002270 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002271 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002272 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002273 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002274 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275}
2276
2277TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2278 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002279 send_parameters_.options.audio_network_adaptor = true;
2280 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002281 SetSendParameters(send_parameters_);
2282 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002283 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002284 const int initial_num = call_.GetNumCreatedSendStreams();
2285 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002286 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002287 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2288 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002289 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002290 // AudioSendStream not expected to be recreated.
2291 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2292 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002293 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002294}
2295
michaelt6672b262017-01-11 10:17:59 -08002296class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2297 : public WebRtcVoiceEngineTestFake {
2298 public:
2299 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2300 : WebRtcVoiceEngineTestFake(
2301 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2302 "Enabled/") {}
2303};
2304
2305TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2306 EXPECT_TRUE(SetupSendStream());
2307 cricket::AudioSendParameters parameters;
2308 parameters.codecs.push_back(kOpusCodec);
2309 SetSendParameters(parameters);
2310 const int initial_num = call_.GetNumCreatedSendStreams();
2311 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2312
2313 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2314 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002315 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2316 constexpr int kMinOverheadBps =
2317 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002318
2319 constexpr int kOpusMinBitrateBps = 6000;
2320 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002321 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002322 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002323 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002324 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002325
Oskar Sundbom78807582017-11-16 11:09:55 +01002326 parameters.options.audio_network_adaptor = true;
2327 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002328 SetSendParameters(parameters);
2329
ossu11bfc532017-02-16 05:37:06 -08002330 constexpr int kMinOverheadWithAnaBps =
2331 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002332
2333 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002335
minyuececec102017-03-27 13:04:25 -07002336 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002337 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002338}
2339
minyuececec102017-03-27 13:04:25 -07002340// This test is similar to
2341// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2342// additional field trial.
2343TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2344 SetRtpSendParameterUpdatesMaxBitrate) {
2345 EXPECT_TRUE(SetupSendStream());
2346 cricket::AudioSendParameters send_parameters;
2347 send_parameters.codecs.push_back(kOpusCodec);
2348 SetSendParameters(send_parameters);
2349
2350 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2351 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2352 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2353
2354 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002355 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002356 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2357
2358 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2359#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2360 constexpr int kMinOverhead = 3333;
2361#else
2362 constexpr int kMinOverhead = 6666;
2363#endif
2364 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2365}
2366
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002368// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002370 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002371 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002372}
2373
2374TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2375 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002376 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002377 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002378 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002379 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002380 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002381 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002382 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002383
solenberg85a04962015-10-27 03:35:21 -07002384 // Check stats for the added streams.
2385 {
2386 cricket::VoiceMediaInfo info;
2387 EXPECT_EQ(true, channel_->GetStats(&info));
2388
2389 // We have added one send stream. We should see the stats we've set.
2390 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002391 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002392 // We have added one receive stream. We should see empty stats.
2393 EXPECT_EQ(info.receivers.size(), 1u);
2394 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2395 }
solenberg1ac56142015-10-13 03:58:19 -07002396
solenberg566ef242015-11-06 15:34:49 -08002397 // Start sending - this affects some reported stats.
2398 {
2399 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002400 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002401 EXPECT_EQ(true, channel_->GetStats(&info));
2402 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002403 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002404 }
2405
solenberg2100c0b2017-03-01 11:29:29 -08002406 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002407 {
2408 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002409 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002410 EXPECT_EQ(true, channel_->GetStats(&info));
2411 EXPECT_EQ(1u, info.senders.size());
2412 EXPECT_EQ(0u, info.receivers.size());
2413 }
solenberg1ac56142015-10-13 03:58:19 -07002414
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002415 // Deliver a new packet - a default receive stream should be created and we
2416 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002417 {
2418 cricket::VoiceMediaInfo info;
2419 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2420 SetAudioReceiveStreamStats();
2421 EXPECT_EQ(true, channel_->GetStats(&info));
2422 EXPECT_EQ(1u, info.senders.size());
2423 EXPECT_EQ(1u, info.receivers.size());
2424 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002425 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002426 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002430// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002433 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2434 EXPECT_TRUE(AddRecvStream(kSsrcY));
2435 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002436}
2437
2438// Test that the local SSRC is the same on sending and receiving channels if the
2439// receive channel is created before the send channel.
2440TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002441 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002442 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002444 cricket::StreamParams::CreateLegacy(kSsrcX)));
2445 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2446 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447}
2448
2449// Test that we can properly receive packets.
2450TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002451 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002452 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002454
2455 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2456 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457}
2458
2459// Test that we can properly receive packets on multiple streams.
2460TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002461 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002462 const uint32_t ssrc1 = 1;
2463 const uint32_t ssrc2 = 2;
2464 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002465 EXPECT_TRUE(AddRecvStream(ssrc1));
2466 EXPECT_TRUE(AddRecvStream(ssrc2));
2467 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002468 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002469 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002470 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002472 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473 }
mflodman3d7db262016-04-29 00:57:13 -07002474
2475 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2476 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2477 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2478
2479 EXPECT_EQ(s1.received_packets(), 0);
2480 EXPECT_EQ(s2.received_packets(), 0);
2481 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002482
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002484 EXPECT_EQ(s1.received_packets(), 0);
2485 EXPECT_EQ(s2.received_packets(), 0);
2486 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002487
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002488 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002489 EXPECT_EQ(s1.received_packets(), 1);
2490 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2491 EXPECT_EQ(s2.received_packets(), 0);
2492 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002493
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002495 EXPECT_EQ(s1.received_packets(), 1);
2496 EXPECT_EQ(s2.received_packets(), 1);
2497 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2498 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002499
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002501 EXPECT_EQ(s1.received_packets(), 1);
2502 EXPECT_EQ(s2.received_packets(), 1);
2503 EXPECT_EQ(s3.received_packets(), 1);
2504 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002505
mflodman3d7db262016-04-29 00:57:13 -07002506 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2507 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2508 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509}
2510
solenberg2100c0b2017-03-01 11:29:29 -08002511// Test that receiving on an unsignaled stream works (a stream is created).
2512TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002513 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002514 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2515
solenberg7e63ef02015-11-20 00:19:43 -08002516 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002517
2518 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002519 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2520 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002521}
2522
solenberg2100c0b2017-03-01 11:29:29 -08002523// Test that receiving N unsignaled stream works (streams will be created), and
2524// that packets are forwarded to them all.
2525TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002526 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002527 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002528 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2529
solenberg2100c0b2017-03-01 11:29:29 -08002530 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002531 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002532 rtc::SetBE32(&packet[8], ssrc);
2533 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002534
solenberg2100c0b2017-03-01 11:29:29 -08002535 // Verify we have one new stream for each loop iteration.
2536 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002537 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2538 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002539 }
mflodman3d7db262016-04-29 00:57:13 -07002540
solenberg2100c0b2017-03-01 11:29:29 -08002541 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002542 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002543 rtc::SetBE32(&packet[8], ssrc);
2544 DeliverPacket(packet, sizeof(packet));
2545
solenbergebb349d2017-03-13 05:46:15 -07002546 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002547 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2548 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2549 }
2550
2551 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2552 constexpr uint32_t kAnotherSsrc = 667;
2553 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002554 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002555
2556 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002557 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002558 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002559 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002560 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2561 EXPECT_EQ(2, streams[i]->received_packets());
2562 }
2563 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2564 EXPECT_EQ(1, streams[i]->received_packets());
2565 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002566 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002567}
2568
solenberg2100c0b2017-03-01 11:29:29 -08002569// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002570// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002571TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002572 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002573 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002574 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2575
2576 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002577 const uint32_t signaled_ssrc = 1;
2578 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002579 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002580 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002581 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2582 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002583 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002584
2585 // Note that the first unknown SSRC cannot be 0, because we only support
2586 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002587 const uint32_t unsignaled_ssrc = 7011;
2588 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002589 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002590 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2591 packet, sizeof(packet)));
2592 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2593
2594 DeliverPacket(packet, sizeof(packet));
2595 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2596
2597 rtc::SetBE32(&packet[8], signaled_ssrc);
2598 DeliverPacket(packet, sizeof(packet));
2599 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2600 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002601}
2602
solenberg4904fb62017-02-17 12:01:14 -08002603// Two tests to verify that adding a receive stream with the same SSRC as a
2604// previously added unsignaled stream will only recreate underlying stream
2605// objects if the stream parameters have changed.
2606TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2607 EXPECT_TRUE(SetupChannel());
2608
2609 // Spawn unsignaled stream with SSRC=1.
2610 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2611 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2612 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2613 sizeof(kPcmuFrame)));
2614
2615 // Verify that the underlying stream object in Call is not recreated when a
2616 // stream with SSRC=1 is added.
2617 const auto& streams = call_.GetAudioReceiveStreams();
2618 EXPECT_EQ(1, streams.size());
2619 int audio_receive_stream_id = streams.front()->id();
2620 EXPECT_TRUE(AddRecvStream(1));
2621 EXPECT_EQ(1, streams.size());
2622 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2623}
2624
2625TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2626 EXPECT_TRUE(SetupChannel());
2627
2628 // Spawn unsignaled stream with SSRC=1.
2629 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2630 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2631 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2632 sizeof(kPcmuFrame)));
2633
2634 // Verify that the underlying stream object in Call *is* recreated when a
2635 // stream with SSRC=1 is added, and which has changed stream parameters.
2636 const auto& streams = call_.GetAudioReceiveStreams();
2637 EXPECT_EQ(1, streams.size());
2638 int audio_receive_stream_id = streams.front()->id();
2639 cricket::StreamParams stream_params;
2640 stream_params.ssrcs.push_back(1);
2641 stream_params.sync_label = "sync_label";
2642 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2643 EXPECT_EQ(1, streams.size());
2644 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2645}
2646
solenberg0a617e22015-10-20 15:49:38 -07002647// Test that we properly handle failures to add a receive stream.
2648TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002649 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002650 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002651 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652}
2653
solenberg0a617e22015-10-20 15:49:38 -07002654// Test that we properly handle failures to add a send stream.
2655TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002657 voe_.set_fail_create_channel(true);
2658 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2659}
2660
solenberg1ac56142015-10-13 03:58:19 -07002661// Test that AddRecvStream creates new stream.
2662TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002665 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002666 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667}
2668
2669// Test that after adding a recv stream, we do not decode more codecs than
2670// those previously passed into SetRecvCodecs.
2671TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002672 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002673 cricket::AudioRecvParameters parameters;
2674 parameters.codecs.push_back(kIsacCodec);
2675 parameters.codecs.push_back(kPcmuCodec);
2676 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002677 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002678 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2679 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2680 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002681}
2682
2683// Test that we properly clean up any streams that were added, even if
2684// not explicitly removed.
2685TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002686 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002687 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002688 EXPECT_TRUE(AddRecvStream(1));
2689 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2691 delete channel_;
2692 channel_ = NULL;
2693 EXPECT_EQ(0, voe_.GetNumChannels());
2694}
2695
wu@webrtc.org78187522013-10-07 23:32:02 +00002696TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002697 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002698 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002699}
2700
2701TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002703 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002704 // Manually delete channel to simulate a failure.
2705 int channel = voe_.GetLastChannel();
2706 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2707 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002708 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002709 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002710 EXPECT_NE(channel, new_channel);
2711 // The last created channel is deleted too.
2712 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002713}
2714
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002715// Test the InsertDtmf on default send stream as caller.
2716TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002717 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718}
2719
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002720// Test the InsertDtmf on default send stream as callee
2721TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002722 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002723}
2724
2725// Test the InsertDtmf on specified send stream as caller.
2726TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002727 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002728}
2729
2730// Test the InsertDtmf on specified send stream as callee.
2731TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002732 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733}
2734
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002736 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002737 EXPECT_CALL(adm_,
2738 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2739 EXPECT_CALL(adm_,
2740 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2741 EXPECT_CALL(adm_,
2742 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002743
solenberg246b8172015-12-08 09:50:23 -08002744 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2745 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746
solenberg246b8172015-12-08 09:50:23 -08002747 // Nothing set in AudioOptions, so everything should be as default.
2748 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002749 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002750 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002751 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2752 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753
2754 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759
2760 // Turn echo cancellation back on, with settings, and make sure
2761 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002762 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002764 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002765 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002767 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2768 // control.
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002771 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002772 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002773
2774 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002775 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002777 send_parameters_.options.delay_agnostic_aec = false;
2778 send_parameters_.options.extended_filter_aec = false;
2779 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002780 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002781
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002782 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002783 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2784 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002785 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002786 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002787
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002789 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002791 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002792 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002793 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002794 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795
2796 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002797 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002799 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002800 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002801 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002802 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002803
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002804 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002805 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2806 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002807 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002808 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002809 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002810 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002812 send_parameters_.options.noise_suppression = false;
2813 send_parameters_.options.highpass_filter = false;
2814 send_parameters_.options.typing_detection = false;
2815 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002816 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002817 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818
solenberg1ac56142015-10-13 03:58:19 -07002819 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002820 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2821 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002822 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002823 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002824 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002825 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002827 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002828}
2829
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002831 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002832 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002833 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002834 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002835 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002836 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002837 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002838 EXPECT_CALL(adm_,
2839 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2840 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2841 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002842 webrtc::AudioProcessing::Config apm_config;
2843 EXPECT_CALL(*apm_, GetConfig())
2844 .Times(10)
2845 .WillRepeatedly(ReturnPointee(&apm_config));
2846 EXPECT_CALL(*apm_, ApplyConfig(_))
2847 .Times(10)
2848 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002849 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002850
kwiberg686a8ef2016-02-26 03:00:35 -08002851 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002852 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002853 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002854 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002855 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002856 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002857
2858 // Have to add a stream to make SetSend work.
2859 cricket::StreamParams stream1;
2860 stream1.ssrcs.push_back(1);
2861 channel1->AddSendStream(stream1);
2862 cricket::StreamParams stream2;
2863 stream2.ssrcs.push_back(2);
2864 channel2->AddSendStream(stream2);
2865
2866 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002867 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002868 parameters_options_all.options.echo_cancellation = true;
2869 parameters_options_all.options.auto_gain_control = true;
2870 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002871 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2872 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002873 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002875 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002876 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002877 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002878 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002879 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002880 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
2882 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002883 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002889 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002891 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002892 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 expected_options.echo_cancellation = true;
2894 expected_options.auto_gain_control = true;
2895 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002896 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002897
2898 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002899 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002900 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002903 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002905 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002907 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002908 expected_options.echo_cancellation = true;
2909 expected_options.auto_gain_control = false;
2910 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002911 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002917 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002919 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002920
solenberg76377c52017-02-21 00:54:31 -08002921 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2922 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002923 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002924 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002925 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002926 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002927 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2930 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002931 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002932 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002933 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002934 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002935 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002938 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2939 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002940 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2941 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002942 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2943 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002944 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002945 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002946 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002947 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002948 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002949 expected_options.echo_cancellation = true;
2950 expected_options.auto_gain_control = false;
2951 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002952 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953}
2954
wu@webrtc.orgde305012013-10-31 15:40:38 +00002955// This test verifies DSCP settings are properly applied on voice media channel.
2956TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002958 cricket::FakeNetworkInterface network_interface;
2959 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002960 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002961
peahb1c9d1d2017-07-25 15:45:24 -07002962 webrtc::AudioProcessing::Config apm_config;
2963 EXPECT_CALL(*apm_, GetConfig())
2964 .Times(3)
2965 .WillRepeatedly(ReturnPointee(&apm_config));
2966 EXPECT_CALL(*apm_, ApplyConfig(_))
2967 .Times(3)
2968 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002969 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002970
solenbergbc37fc82016-04-04 09:54:44 -07002971 channel.reset(
2972 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002973 channel->SetInterface(&network_interface);
2974 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2975 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2976
2977 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002978 channel.reset(
2979 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002980 channel->SetInterface(&network_interface);
2981 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2982
2983 // Verify that setting the option to false resets the
2984 // DiffServCodePoint.
2985 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002986 channel.reset(
2987 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002988 channel->SetInterface(&network_interface);
2989 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2990 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2991
2992 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002993}
2994
solenberg1ac56142015-10-13 03:58:19 -07002995TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002996 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997 cricket::WebRtcVoiceMediaChannel* media_channel =
2998 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002999 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003000 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003001 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3003 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3004 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003005 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003006 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007}
3008
solenberg1ac56142015-10-13 03:58:19 -07003009TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003010 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003012 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3013 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3014 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003015 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003016 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003017 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3018 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003019 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003020 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003021 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003022 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023}
3024
solenberg4bac9c52015-10-09 02:32:53 -07003025TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003026 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003027 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003029 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003030 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003031 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3032 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3033 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003034}
3035
solenberg2100c0b2017-03-01 11:29:29 -08003036TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003037 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003038
3039 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003040 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003041 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3042
3043 // Should remember the volume "2" which will be set on new unsignaled streams,
3044 // and also set the gain to 2 on existing unsignaled streams.
3045 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3046 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3047
3048 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3049 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3050 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3051 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3052 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3053 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3054
3055 // Setting gain with SSRC=0 should affect all unsignaled streams.
3056 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003057 if (kMaxUnsignaledRecvStreams > 1) {
3058 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3059 }
solenberg2100c0b2017-03-01 11:29:29 -08003060 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3061
3062 // Setting gain on an individual stream affects only that.
3063 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003064 if (kMaxUnsignaledRecvStreams > 1) {
3065 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3066 }
solenberg2100c0b2017-03-01 11:29:29 -08003067 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003068}
3069
pbos8fc7fa72015-07-15 08:02:58 -07003070TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003071 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003072 const std::string kSyncLabel = "AvSyncLabel";
3073
solenbergff976312016-03-30 23:28:51 -07003074 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003075 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3076 sp.sync_label = kSyncLabel;
3077 // Creating two channels to make sure that sync label is set properly for both
3078 // the default voice channel and following ones.
3079 EXPECT_TRUE(channel_->AddRecvStream(sp));
3080 sp.ssrcs[0] += 1;
3081 EXPECT_TRUE(channel_->AddRecvStream(sp));
3082
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003084 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003085 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003086 << "SyncGroup should be set based on sync_label";
3087 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003088 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003089 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003090}
3091
solenberg3a941542015-11-16 07:34:50 -08003092// TODO(solenberg): Remove, once recv streams are configured through Call.
3093// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003094TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 // Test that setting the header extensions results in the expected state
3096 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003097 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 ssrcs.push_back(223);
3099 ssrcs.push_back(224);
3100
solenbergff976312016-03-30 23:28:51 -07003101 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003102 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003103 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003104 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 cricket::StreamParams::CreateLegacy(ssrc)));
3106 }
3107
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003108 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003109 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003110 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003111 EXPECT_NE(nullptr, s);
3112 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3113 }
3114
3115 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003116 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003117 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003118 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003119 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003120 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003121 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003122 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123 EXPECT_NE(nullptr, s);
3124 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003125 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3126 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 for (const auto& s_ext : s_exts) {
3128 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003129 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 }
3131 }
3132 }
3133 }
3134
3135 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003136 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003137 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003138 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 EXPECT_NE(nullptr, s);
3140 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3141 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003142}
3143
3144TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3145 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003146 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003147 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003148 static const unsigned char kRtcp[] = {
3149 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3150 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3153 };
jbaucheec21bd2016-03-20 06:15:43 -07003154 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155
solenbergff976312016-03-30 23:28:51 -07003156 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003157 cricket::WebRtcVoiceMediaChannel* media_channel =
3158 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003159 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003160 EXPECT_TRUE(media_channel->AddRecvStream(
3161 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3162
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003163 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003164 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003165 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003166 EXPECT_EQ(0, s->received_packets());
3167 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3168 EXPECT_EQ(1, s->received_packets());
3169 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3170 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003171}
Minyue2013aec2015-05-13 14:14:42 +02003172
solenberg0a617e22015-10-20 15:49:38 -07003173// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003174// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003175TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003177 EXPECT_TRUE(AddRecvStream(kSsrcY));
3178 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003179 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003180 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3181 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3182 EXPECT_TRUE(AddRecvStream(kSsrcW));
3183 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003184}
3185
solenberg7602aab2016-11-14 11:30:07 -08003186TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3187 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003188 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003189 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003190 cricket::StreamParams::CreateLegacy(kSsrcY)));
3191 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3192 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3193 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003194 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003195 cricket::StreamParams::CreateLegacy(kSsrcW)));
3196 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3197 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003198}
stefan658910c2015-09-03 05:48:32 -07003199
deadbeef884f5852016-01-15 09:20:04 -08003200TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003201 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003202 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3203 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003204
3205 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003206 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3207 EXPECT_TRUE(AddRecvStream(kSsrcX));
3208 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003209
3210 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003211 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3212 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003213
3214 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003215 channel_->SetRawAudioSink(kSsrcX, nullptr);
3216 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003217}
3218
solenberg2100c0b2017-03-01 11:29:29 -08003219TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003220 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003221 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3222 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003223 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3224 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003225
3226 // Should be able to set a default sink even when no stream exists.
3227 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3228
solenberg2100c0b2017-03-01 11:29:29 -08003229 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3230 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003231 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003232 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003233
3234 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003235 channel_->SetRawAudioSink(kSsrc0, nullptr);
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003237
3238 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003239 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3240 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003241
3242 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003243 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003244 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3246
3247 // Spawn another unsignaled stream - it should be assigned the default sink
3248 // and the previous unsignaled stream should lose it.
3249 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3250 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3251 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3252 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003253 if (kMaxUnsignaledRecvStreams > 1) {
3254 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3255 }
solenberg2100c0b2017-03-01 11:29:29 -08003256 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3257
3258 // Reset the default sink - the second unsignaled stream should lose it.
3259 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003260 if (kMaxUnsignaledRecvStreams > 1) {
3261 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3262 }
solenberg2100c0b2017-03-01 11:29:29 -08003263 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3264
3265 // Try setting the default sink while two streams exists.
3266 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003267 if (kMaxUnsignaledRecvStreams > 1) {
3268 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3269 }
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3271
3272 // Try setting the sink for the first unsignaled stream using its known SSRC.
3273 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003274 if (kMaxUnsignaledRecvStreams > 1) {
3275 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3276 }
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003278 if (kMaxUnsignaledRecvStreams > 1) {
3279 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3280 }
deadbeef884f5852016-01-15 09:20:04 -08003281}
3282
skvlad7a43d252016-03-22 15:32:27 -07003283// Test that, just like the video channel, the voice channel communicates the
3284// network state to the call.
3285TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003286 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003287
3288 EXPECT_EQ(webrtc::kNetworkUp,
3289 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3290 EXPECT_EQ(webrtc::kNetworkUp,
3291 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3292
3293 channel_->OnReadyToSend(false);
3294 EXPECT_EQ(webrtc::kNetworkDown,
3295 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3296 EXPECT_EQ(webrtc::kNetworkUp,
3297 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3298
3299 channel_->OnReadyToSend(true);
3300 EXPECT_EQ(webrtc::kNetworkUp,
3301 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3302 EXPECT_EQ(webrtc::kNetworkUp,
3303 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3304}
3305
aleloi18e0b672016-10-04 02:45:47 -07003306// Test that playout is still started after changing parameters
3307TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3308 SetupRecvStream();
3309 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003310 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003311
3312 // Changing RTP header extensions will recreate the AudioReceiveStream.
3313 cricket::AudioRecvParameters parameters;
3314 parameters.extensions.push_back(
3315 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3316 channel_->SetRecvParameters(parameters);
3317
solenberg2100c0b2017-03-01 11:29:29 -08003318 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003319}
3320
Zhi Huangfa266ef2017-12-13 10:27:46 -08003321// Tests when GetSources is called with non-existing ssrc, it will return an
3322// empty list of RtpSource without crashing.
3323TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3324 // Setup an recv stream with |kSsrcX|.
3325 SetupRecvStream();
3326 cricket::WebRtcVoiceMediaChannel* media_channel =
3327 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3328 // Call GetSources with |kSsrcY| which doesn't exist.
3329 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3330 EXPECT_EQ(0u, sources.size());
3331}
3332
stefan658910c2015-09-03 05:48:32 -07003333// Tests that the library initializes and shuts down properly.
3334TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003335 // If the VoiceEngine wants to gather available codecs early, that's fine but
3336 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003337 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003338 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003339 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003340 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003341 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003342 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003343 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003344 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003345 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003346 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003347 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3348 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003349 EXPECT_TRUE(channel != nullptr);
3350 delete channel;
solenbergff976312016-03-30 23:28:51 -07003351}
stefan658910c2015-09-03 05:48:32 -07003352
solenbergff976312016-03-30 23:28:51 -07003353// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003354TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3355 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg2a877972017-12-15 16:42:15 +01003356 EXPECT_CALL(adm, AddRef()).Times(5);
Niels Möller6f72f562017-10-19 13:15:17 +02003357 EXPECT_CALL(adm, Release())
Fredrik Solenberg2a877972017-12-15 16:42:15 +01003358 .Times(5)
Niels Möller6f72f562017-10-19 13:15:17 +02003359 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003360 {
peaha9cc40b2017-06-29 08:32:09 -07003361 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003362 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003363 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003364 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003365 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003366 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003367 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003368 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003369 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003370 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3371 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3372 EXPECT_TRUE(channel != nullptr);
3373 delete channel;
3374 }
stefan658910c2015-09-03 05:48:32 -07003375}
3376
ossu20a4b3f2017-04-27 02:08:52 -07003377// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3378TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003379 // TODO(ossu): Why are the payload types of codecs with non-static payload
3380 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003381 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003382 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003383 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003384 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003385 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003386 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003387 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003388 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003389 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3390 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3391 (clockrate == 0 || codec.clockrate == clockrate);
3392 };
3393 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003394 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003395 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003396 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003397 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003399 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003400 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003401 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003402 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003403 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003404 EXPECT_EQ(126, codec.id);
3405 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3406 // Remove these checks once both send and receive side assigns payload types
3407 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003408 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003409 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003410 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003411 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003412 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003413 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003414 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003415 EXPECT_EQ(111, codec.id);
3416 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3417 EXPECT_EQ("10", codec.params.find("minptime")->second);
3418 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3419 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003420 }
3421 }
stefan658910c2015-09-03 05:48:32 -07003422}
3423
3424// Tests that VoE supports at least 32 channels
3425TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003426 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003427 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003428 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003429 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003430 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003431 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003432 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003433 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003434 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003435 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003436
3437 cricket::VoiceMediaChannel* channels[32];
3438 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003439 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003440 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3441 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003442 if (!channel)
3443 break;
stefan658910c2015-09-03 05:48:32 -07003444 channels[num_channels++] = channel;
3445 }
3446
tfarina5237aaf2015-11-10 23:44:30 -08003447 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003448 EXPECT_EQ(expected, num_channels);
3449
3450 while (num_channels > 0) {
3451 delete channels[--num_channels];
3452 }
stefan658910c2015-09-03 05:48:32 -07003453}
3454
3455// Test that we set our preferred codecs properly.
3456TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003457 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3458 // - Check that our builtin codecs are usable by Channel.
3459 // - The codecs provided by the engine is usable by Channel.
3460 // It does not check that the codecs in the RecvParameters are actually
3461 // what we sent in - though it's probably reasonable to expect so, if
3462 // SetRecvParameters returns true.
3463 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003464 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003465 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003466 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003467 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003468 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003469 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003470 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003471 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003472 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003473 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003474 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3475 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003476 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003477 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003478 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003479}
ossu9def8002017-02-09 05:14:32 -08003480
3481TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3482 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003483 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3484 {48000, 2, 16000, 10000, 20000}};
3485 spec1.info.allow_comfort_noise = false;
3486 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003487 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003488 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3489 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003490 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003491 specs.push_back(webrtc::AudioCodecSpec{
3492 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3493 {16000, 1, 13300}});
3494 specs.push_back(
3495 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3496 specs.push_back(
3497 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003498
ossueb1fde42017-05-02 06:46:30 -07003499 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3500 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3501 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003502 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003503 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003504 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003505 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003506
peaha9cc40b2017-06-29 08:32:09 -07003507 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003508 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003509 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003510 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003511 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003512 auto codecs = engine.recv_codecs();
3513 EXPECT_EQ(11, codecs.size());
3514
3515 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3516 // check the actual values safely, to provide better test results.
3517 auto get_codec =
3518 [&codecs](size_t index) -> const cricket::AudioCodec& {
3519 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3520 if (codecs.size() > index)
3521 return codecs[index];
3522 return missing_codec;
3523 };
3524
3525 // Ensure the general codecs are generated first and in order.
3526 for (size_t i = 0; i != specs.size(); ++i) {
3527 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3528 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3529 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3530 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3531 }
3532
3533 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003534 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003535 auto find_codec =
3536 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3537 for (size_t i = 0; i != codecs.size(); ++i) {
3538 const cricket::AudioCodec& codec = codecs[i];
3539 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3540 codec.clockrate == format.clockrate_hz &&
3541 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003542 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003543 }
3544 }
3545 return -1;
3546 };
3547
3548 // Ensure all supplementary codecs are generated last. Their internal ordering
3549 // is not important.
3550 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3551 const int num_specs = static_cast<int>(specs.size());
3552 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3553 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3554 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3555 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3556 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3557 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3558 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3559}