blob: 2c312531147664fa138ea540b6850e0b40187a99 [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>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "api/audio_codecs/builtin_audio_decoder_factory.h"
14#include "api/audio_codecs/builtin_audio_encoder_factory.h"
15#include "call/call.h"
16#include "logging/rtc_event_log/rtc_event_log.h"
17#include "media/base/fakemediaengine.h"
18#include "media/base/fakenetworkinterface.h"
19#include "media/base/fakertp.h"
20#include "media/base/mediaconstants.h"
21#include "media/engine/fakewebrtccall.h"
22#include "media/engine/fakewebrtcvoiceengine.h"
23#include "media/engine/webrtcvoiceengine.h"
24#include "modules/audio_device/include/mock_audio_device.h"
25#include "modules/audio_processing/include/mock_audio_processing.h"
26#include "pc/channel.h"
27#include "rtc_base/arraysize.h"
28#include "rtc_base/byteorder.h"
29#include "rtc_base/safe_conversions.h"
30#include "rtc_base/scoped_ref_ptr.h"
31#include "test/field_trial.h"
32#include "test/gtest.h"
33#include "test/mock_audio_decoder_factory.h"
34#include "test/mock_audio_encoder_factory.h"
35#include "voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070039using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070040using testing::ReturnPointee;
41using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070042using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000043
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020044namespace {
45
solenberg418b7d32017-06-13 00:38:27 -070046constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070047
deadbeef67cf2c12016-04-13 10:07:16 -070048const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
49const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070050const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
52const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
54const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080055const cricket::AudioCodec
56 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
57const cricket::AudioCodec
58 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
59
solenberg2100c0b2017-03-01 11:29:29 -080060const uint32_t kSsrc0 = 0;
61const uint32_t kSsrc1 = 1;
62const uint32_t kSsrcX = 0x99;
63const uint32_t kSsrcY = 0x17;
64const uint32_t kSsrcZ = 0x42;
65const uint32_t kSsrcW = 0x02;
66const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067
solenberg971cab02016-06-14 10:02:41 -070068constexpr int kRtpHistoryMs = 5000;
69
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070class FakeVoEWrapper : public cricket::VoEWrapper {
71 public:
72 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070073 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 }
75};
skvlad11a9cbf2016-10-07 11:53:05 -070076
solenberg76377c52017-02-21 00:54:31 -080077class MockTransmitMixer : public webrtc::voe::TransmitMixer {
78 public:
79 MockTransmitMixer() = default;
80 virtual ~MockTransmitMixer() = default;
81
82 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
83};
solenberg9a5f032222017-03-15 06:14:12 -070084
85void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
86 RTC_DCHECK(adm);
87 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
88 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
89#if !defined(WEBRTC_IOS)
90 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
91 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
92 ChannelType::kChannelBoth)).WillOnce(Return(0));
93#if defined(WEBRTC_WIN)
94 EXPECT_CALL(*adm, SetRecordingDevice(
95 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
96 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
97 .WillOnce(Return(0));
98#else
99 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
100#endif // #if defined(WEBRTC_WIN)
101 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
102 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
103 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
104 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
105#if defined(WEBRTC_WIN)
106 EXPECT_CALL(*adm, SetPlayoutDevice(
107 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
108 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
109 .WillOnce(Return(0));
110#else
111 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
112#endif // #if defined(WEBRTC_WIN)
113 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
114 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
115 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
116#endif // #if !defined(WEBRTC_IOS)
117 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
118 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
119 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
121}
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::_));
135 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
136 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800137 StrictMock<MockTransmitMixer> transmit_mixer;
138 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700139 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700140 EXPECT_FALSE(voe.IsInited());
141 {
ossuc54071d2016-08-17 02:45:41 -0700142 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700143 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700144 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700145 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700146 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700147 EXPECT_TRUE(voe.IsInited());
148 }
149 EXPECT_FALSE(voe.IsInited());
150}
151
deadbeef884f5852016-01-15 09:20:04 -0800152class FakeAudioSink : public webrtc::AudioSinkInterface {
153 public:
154 void OnData(const Data& audio) override {}
155};
156
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800157class FakeAudioSource : public cricket::AudioSource {
158 void SetSink(Sink* sink) override {}
159};
160
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161class WebRtcVoiceEngineTestFake : public testing::Test {
162 public:
stefanba4c0e42016-02-04 04:12:24 -0800163 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
164
165 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700166 : apm_(new rtc::RefCountedObject<
167 StrictMock<webrtc::test::MockAudioProcessing>>()),
168 apm_gc_(*apm_->gain_control()),
169 apm_ec_(*apm_->echo_cancellation()),
170 apm_ns_(*apm_->noise_suppression()),
171 apm_vd_(*apm_->voice_detection()),
172 call_(webrtc::Call::Config(&event_log_)),
173 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700174 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800175 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700176 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800177 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700178 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
179 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700180 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
181 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
182 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800183 // Default Options.
184 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
185 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
186 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
190 // Init does not overwrite default AGC config.
191 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
192 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
193 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
194 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
195 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
196 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700197 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800198 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700199 // factories. Those tests should probably be moved elsewhere.
200 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
201 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
202 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700203 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700204 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700205 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200206 send_parameters_.codecs.push_back(kPcmuCodec);
207 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800208 // Default Options.
209 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700213 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700214 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
215 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupRecvStream() {
220 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700221 return false;
222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupSendStream() {
227 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000228 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 }
solenberg2100c0b2017-03-01 11:29:29 -0800230 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800231 return false;
232 }
peaha9cc40b2017-06-29 08:32:09 -0700233 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800234 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 }
solenberg8189b022016-06-14 12:13:00 -0700236
237 bool AddRecvStream(uint32_t ssrc) {
238 EXPECT_TRUE(channel_);
239 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
240 }
241
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000242 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700243 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700244 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800245 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
246 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700247 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800248 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249 }
solenberg8189b022016-06-14 12:13:00 -0700250
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700252 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000253 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200256 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 }
259
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100260 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
261 const auto* send_stream = call_.GetAudioSendStream(ssrc);
262 EXPECT_TRUE(send_stream);
263 return *send_stream;
264 }
265
deadbeef884f5852016-01-15 09:20:04 -0800266 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
267 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
268 EXPECT_TRUE(recv_stream);
269 return *recv_stream;
270 }
271
solenberg3a941542015-11-16 07:34:50 -0800272 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800273 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800274 }
275
solenberg7add0582015-11-20 09:59:34 -0800276 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800277 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800278 }
279
solenberg059fb442016-10-26 05:12:24 -0700280 void SetSend(bool enable) {
281 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700282 if (enable) {
283 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
284 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
285 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700286 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700287 }
solenberg059fb442016-10-26 05:12:24 -0700288 channel_->SetSend(enable);
289 }
290
291 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700292 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700293 ASSERT_TRUE(channel_);
294 EXPECT_TRUE(channel_->SetSendParameters(params));
295 }
296
minyue6b825df2016-10-31 04:08:32 -0700297 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
298 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700299 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700300 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700301 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700302 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700303 }
304 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700305 }
306
solenbergffbbcac2016-11-17 05:25:37 -0800307 void TestInsertDtmf(uint32_t ssrc, bool caller,
308 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700309 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700311 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 // send stream.
313 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800314 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700318 SetSendParameters(send_parameters_);
319 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800322 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000325
326 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700327 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800328 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800330 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331 }
332
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800334 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100336 // Test send.
337 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800338 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100339 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800340 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800341 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800342 EXPECT_EQ(codec.id, telephone_event.payload_type);
343 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(2, telephone_event.event_code);
345 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 }
347
348 // Test that send bandwidth is set correctly.
349 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000350 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
351 // |expected_result| is the expected result from SetMaxSendBandwidth().
352 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700353 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
354 int max_bitrate,
355 bool expected_result,
356 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200357 cricket::AudioSendParameters parameters;
358 parameters.codecs.push_back(codec);
359 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700360 if (expected_result) {
361 SetSendParameters(parameters);
362 } else {
363 EXPECT_FALSE(channel_->SetSendParameters(parameters));
364 }
solenberg2100c0b2017-03-01 11:29:29 -0800365 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366 }
367
skvlade0d46372016-04-07 22:59:22 -0700368 // Sets the per-stream maximum bitrate limit for the specified SSRC.
369 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700370 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700371 EXPECT_EQ(1UL, parameters.encodings.size());
372
deadbeefe702b302017-02-04 12:09:01 -0800373 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700374 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700375 }
376
solenberg059fb442016-10-26 05:12:24 -0700377 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700378 cricket::AudioSendParameters send_parameters;
379 send_parameters.codecs.push_back(codec);
380 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700381 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700382 }
383
ossu20a4b3f2017-04-27 02:08:52 -0700384 void CheckSendCodecBitrate(int32_t ssrc,
385 const char expected_name[],
386 int expected_bitrate) {
387 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
388 EXPECT_EQ(expected_name, spec->format.name);
389 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700390 }
391
ossu20a4b3f2017-04-27 02:08:52 -0700392 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
393 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700394 }
395
minyue6b825df2016-10-31 04:08:32 -0700396 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
397 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
401 int global_max,
402 int stream_max,
403 bool expected_result,
404 int expected_codec_bitrate) {
405 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800406 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700407
408 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700409 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800410 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700411
412 // Verify that reading back the parameters gives results
413 // consistent with the Set() result.
414 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800415 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700416 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
417 EXPECT_EQ(expected_result ? stream_max : -1,
418 resulting_parameters.encodings[0].max_bitrate_bps);
419
420 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800421 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700422 }
423
stefan13f1a0a2016-11-30 07:22:58 -0800424 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
425 int expected_min_bitrate_bps,
426 const char* start_bitrate_kbps,
427 int expected_start_bitrate_bps,
428 const char* max_bitrate_kbps,
429 int expected_max_bitrate_bps) {
430 EXPECT_TRUE(SetupSendStream());
431 auto& codecs = send_parameters_.codecs;
432 codecs.clear();
433 codecs.push_back(kOpusCodec);
434 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
436 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
437 SetSendParameters(send_parameters_);
438
439 EXPECT_EQ(expected_min_bitrate_bps,
440 call_.GetConfig().bitrate_config.min_bitrate_bps);
441 EXPECT_EQ(expected_start_bitrate_bps,
442 call_.GetConfig().bitrate_config.start_bitrate_bps);
443 EXPECT_EQ(expected_max_bitrate_bps,
444 call_.GetConfig().bitrate_config.max_bitrate_bps);
445 }
446
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000447 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700448 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
453 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(
455 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700461 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800462 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 // Ensure extension is set properly.
465 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700466 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700467 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
solenberg7add0582015-11-20 09:59:34 -0800472 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800474 cricket::StreamParams::CreateLegacy(kSsrcY)));
475 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
476 call_.GetAudioSendStream(kSsrcY));
477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200482 send_parameters_.codecs.push_back(kPcmuCodec);
483 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 }
488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700490 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
495 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(
497 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800498 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800502 recv_parameters_.extensions.clear();
503 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 // Ensure extension is set properly.
507 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700508 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800509 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
511 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
solenberg7add0582015-11-20 09:59:34 -0800514 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_TRUE(AddRecvStream(kSsrcY));
516 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
517 call_.GetAudioReceiveStream(kSsrcY));
518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521
522 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800523 recv_parameters_.extensions.clear();
524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000527 }
528
solenberg85a04962015-10-27 03:35:21 -0700529 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
530 webrtc::AudioSendStream::Stats stats;
531 stats.local_ssrc = 12;
532 stats.bytes_sent = 345;
533 stats.packets_sent = 678;
534 stats.packets_lost = 9012;
535 stats.fraction_lost = 34.56f;
536 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800537 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700538 stats.ext_seqnum = 789;
539 stats.jitter_ms = 12;
540 stats.rtt_ms = 345;
541 stats.audio_level = 678;
542 stats.aec_quality_min = 9.01f;
543 stats.echo_delay_median_ms = 234;
544 stats.echo_delay_std_ms = 567;
545 stats.echo_return_loss = 890;
546 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700547 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800548 stats.residual_echo_likelihood_recent_max = 0.6f;
ivoce1198e02017-09-08 08:13:19 -0700549 stats.ana_statistics.bitrate_action_counter = rtc::Optional<uint32_t>(321);
550 stats.ana_statistics.channel_action_counter = rtc::Optional<uint32_t>(432);
551 stats.ana_statistics.dtx_action_counter = rtc::Optional<uint32_t>(543);
552 stats.ana_statistics.fec_action_counter = rtc::Optional<uint32_t>(654);
ivoc0d0b9122017-09-08 13:24:21 -0700553 stats.ana_statistics.frame_length_increase_counter =
ivoce1198e02017-09-08 08:13:19 -0700554 rtc::Optional<uint32_t>(765);
ivoc0d0b9122017-09-08 13:24:21 -0700555 stats.ana_statistics.frame_length_decrease_counter =
556 rtc::Optional<uint32_t>(876);
557 stats.ana_statistics.uplink_packet_loss_fraction =
558 rtc::Optional<float>(987.0);
solenberg85a04962015-10-27 03:35:21 -0700559 stats.typing_noise_detected = true;
560 return stats;
561 }
562 void SetAudioSendStreamStats() {
563 for (auto* s : call_.GetAudioSendStreams()) {
564 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200565 }
solenberg85a04962015-10-27 03:35:21 -0700566 }
solenberg566ef242015-11-06 15:34:49 -0800567 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
568 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700569 const auto stats = GetAudioSendStreamStats();
570 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
571 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
572 EXPECT_EQ(info.packets_sent, stats.packets_sent);
573 EXPECT_EQ(info.packets_lost, stats.packets_lost);
574 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
575 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800576 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700577 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
578 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
579 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
580 EXPECT_EQ(info.audio_level, stats.audio_level);
581 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
582 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
583 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
584 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
585 EXPECT_EQ(info.echo_return_loss_enhancement,
586 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700587 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800588 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
589 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700590 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
591 stats.ana_statistics.bitrate_action_counter);
592 EXPECT_EQ(info.ana_statistics.channel_action_counter,
593 stats.ana_statistics.channel_action_counter);
594 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
595 stats.ana_statistics.dtx_action_counter);
596 EXPECT_EQ(info.ana_statistics.fec_action_counter,
597 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700598 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
599 stats.ana_statistics.frame_length_increase_counter);
600 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
601 stats.ana_statistics.frame_length_decrease_counter);
602 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
603 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800604 EXPECT_EQ(info.typing_noise_detected,
605 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700606 }
607
608 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
609 webrtc::AudioReceiveStream::Stats stats;
610 stats.remote_ssrc = 123;
611 stats.bytes_rcvd = 456;
612 stats.packets_rcvd = 768;
613 stats.packets_lost = 101;
614 stats.fraction_lost = 23.45f;
615 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800616 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700617 stats.ext_seqnum = 678;
618 stats.jitter_ms = 901;
619 stats.jitter_buffer_ms = 234;
620 stats.jitter_buffer_preferred_ms = 567;
621 stats.delay_estimate_ms = 890;
622 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700623 stats.total_samples_received = 5678901;
624 stats.concealed_samples = 234;
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);
solenberg85a04962015-10-27 03:35:21 -0700664 EXPECT_EQ(info.expand_rate, stats.expand_rate);
665 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
666 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200667 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700668 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
669 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200670 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700671 stats.decoding_calls_to_silence_generator);
672 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
673 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
674 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
675 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
676 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700677 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700678 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200679 }
hbos1acfbd22016-11-17 23:43:29 -0800680 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
681 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
682 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
683 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
684 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
685 codec.ToCodecParameters());
686 }
687 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
688 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
689 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
690 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
691 codec.ToCodecParameters());
692 }
693 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200694
peah8271d042016-11-22 07:24:52 -0800695 bool IsHighPassFilterEnabled() {
696 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
697 }
698
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700700 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700701 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800702 webrtc::test::MockGainControl& apm_gc_;
703 webrtc::test::MockEchoCancellation& apm_ec_;
704 webrtc::test::MockNoiseSuppression& apm_ns_;
705 webrtc::test::MockVoiceDetection& apm_vd_;
706 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700707 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200708 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700710 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700711 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200712 cricket::AudioSendParameters send_parameters_;
713 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800714 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700715 webrtc::AudioProcessing::Config apm_config_;
716
stefanba4c0e42016-02-04 04:12:24 -0800717 private:
718 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719};
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721// Tests that we can create and destroy a channel.
722TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700723 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724}
725
solenberg31fec402016-05-06 02:13:12 -0700726// Test that we can add a send stream and that it has the correct defaults.
727TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
728 EXPECT_TRUE(SetupChannel());
729 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800730 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
731 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
732 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700733 EXPECT_EQ("", config.rtp.c_name);
734 EXPECT_EQ(0u, config.rtp.extensions.size());
735 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
736 config.send_transport);
737}
738
739// Test that we can add a receive stream and that it has the correct defaults.
740TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
741 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800742 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700743 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800744 GetRecvStreamConfig(kSsrcX);
745 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700746 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
747 EXPECT_FALSE(config.rtp.transport_cc);
748 EXPECT_EQ(0u, config.rtp.extensions.size());
749 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
750 config.rtcp_send_transport);
751 EXPECT_EQ("", config.sync_group);
752}
753
stefanba4c0e42016-02-04 04:12:24 -0800754TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700755 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800756 bool opus_found = false;
757 for (cricket::AudioCodec codec : codecs) {
758 if (codec.name == "opus") {
759 EXPECT_TRUE(HasTransportCc(codec));
760 opus_found = true;
761 }
762 }
763 EXPECT_TRUE(opus_found);
764}
765
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766// Test that we set our inbound codecs properly, including changing PT.
767TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700768 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200769 cricket::AudioRecvParameters parameters;
770 parameters.codecs.push_back(kIsacCodec);
771 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800772 parameters.codecs.push_back(kTelephoneEventCodec1);
773 parameters.codecs.push_back(kTelephoneEventCodec2);
774 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 parameters.codecs[2].id = 126;
776 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800777 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700778 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
779 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
780 {{0, {"PCMU", 8000, 1}},
781 {106, {"ISAC", 16000, 1}},
782 {126, {"telephone-event", 8000, 1}},
783 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784}
785
786// Test that we fail to set an unknown inbound codec.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700791 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200792 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793}
794
795// Test that we fail if we have duplicate types in the inbound list.
796TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700797 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 cricket::AudioRecvParameters parameters;
799 parameters.codecs.push_back(kIsacCodec);
800 parameters.codecs.push_back(kCn16000Codec);
801 parameters.codecs[1].id = kIsacCodec.id;
802 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803}
804
805// Test that we can decode OPUS without stereo parameters.
806TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700807 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200808 cricket::AudioRecvParameters parameters;
809 parameters.codecs.push_back(kIsacCodec);
810 parameters.codecs.push_back(kPcmuCodec);
811 parameters.codecs.push_back(kOpusCodec);
812 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800813 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700814 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
815 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
816 {{0, {"PCMU", 8000, 1}},
817 {103, {"ISAC", 16000, 1}},
818 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that we can decode OPUS with stereo = 0.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700823 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 cricket::AudioRecvParameters parameters;
825 parameters.codecs.push_back(kIsacCodec);
826 parameters.codecs.push_back(kPcmuCodec);
827 parameters.codecs.push_back(kOpusCodec);
828 parameters.codecs[2].params["stereo"] = "0";
829 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800830 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700831 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
832 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
833 {{0, {"PCMU", 8000, 1}},
834 {103, {"ISAC", 16000, 1}},
835 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836}
837
838// Test that we can decode OPUS with stereo = 1.
839TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700840 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 cricket::AudioRecvParameters parameters;
842 parameters.codecs.push_back(kIsacCodec);
843 parameters.codecs.push_back(kPcmuCodec);
844 parameters.codecs.push_back(kOpusCodec);
845 parameters.codecs[2].params["stereo"] = "1";
846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800847 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700848 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
849 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
850 {{0, {"PCMU", 8000, 1}},
851 {103, {"ISAC", 16000, 1}},
852 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that changes to recv codecs are applied to all streams.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800861 parameters.codecs.push_back(kTelephoneEventCodec1);
862 parameters.codecs.push_back(kTelephoneEventCodec2);
863 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 parameters.codecs[2].id = 126;
865 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700866 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
867 EXPECT_TRUE(AddRecvStream(ssrc));
868 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {106, {"ISAC", 16000, 1}},
872 {126, {"telephone-event", 8000, 1}},
873 {107, {"telephone-event", 32000, 1}}})));
874 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875}
876
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883
solenberg2100c0b2017-03-01 11:29:29 -0800884 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800885 ASSERT_EQ(1, dm.count(106));
886 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887}
888
889// Test that we can apply the same set of codecs again while playing.
890TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700891 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200892 cricket::AudioRecvParameters parameters;
893 parameters.codecs.push_back(kIsacCodec);
894 parameters.codecs.push_back(kCn16000Codec);
895 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700896 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898
deadbeefcb383672017-04-26 16:28:42 -0700899 // Remapping a payload type to a different codec should fail.
900 parameters.codecs[0] = kOpusCodec;
901 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800903 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904}
905
906// Test that we can add a codec while playing.
907TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700908 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200909 cricket::AudioRecvParameters parameters;
910 parameters.codecs.push_back(kIsacCodec);
911 parameters.codecs.push_back(kCn16000Codec);
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700913 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 parameters.codecs.push_back(kOpusCodec);
916 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800917 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
deadbeefcb383672017-04-26 16:28:42 -0700920// Test that we accept adding the same codec with a different payload type.
921// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
922TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
923 EXPECT_TRUE(SetupRecvStream());
924 cricket::AudioRecvParameters parameters;
925 parameters.codecs.push_back(kIsacCodec);
926 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
927
928 ++parameters.codecs[0].id;
929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
930}
931
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700933 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000935 // Test that when autobw is enabled, bitrate is kept as the default
936 // value. autobw is enabled for the following tests because the target
937 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938
939 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700940 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941
942 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700943 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
ossu20a4b3f2017-04-27 02:08:52 -0700945 // opus, default bitrate == 32000 in mono.
946 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947}
948
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000949TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700950 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700953 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
954 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700955 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
959 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
960 // Rates above the max (510000) should be capped.
961 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962}
963
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000964TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700965 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966
967 // Test that we can only set a maximum bitrate for a fixed-rate codec
968 // if it's bigger than the fixed rate.
969
970 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700971 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
972 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
973 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000978}
979
980TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200982 const int kDesiredBitrate = 128000;
983 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700984 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200985 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700986 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000987
988 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800989 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000990
solenberg2100c0b2017-03-01 11:29:29 -0800991 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992}
993
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994// Test that bitrate cannot be set for CBR codecs.
995// Bitrate is ignored if it is higher than the fixed bitrate.
996// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000997TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
1000 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001001 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001002 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001003
1004 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001005 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001006 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001007
1008 send_parameters_.max_bandwidth_bps = 128;
1009 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001010 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011}
1012
skvlade0d46372016-04-07 22:59:22 -07001013// Test that the per-stream bitrate limit and the global
1014// bitrate limit both apply.
1015TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1016 EXPECT_TRUE(SetupSendStream());
1017
ossu20a4b3f2017-04-27 02:08:52 -07001018 // opus, default bitrate == 32000.
1019 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001020 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1021 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1022 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1023
1024 // CBR codecs allow both maximums to exceed the bitrate.
1025 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1026 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1029
1030 // CBR codecs don't allow per stream maximums to be too low.
1031 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1033}
1034
1035// Test that an attempt to set RtpParameters for a stream that does not exist
1036// fails.
1037TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1038 EXPECT_TRUE(SetupChannel());
1039 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001040 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001041 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1042
1043 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001044 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001045}
1046
1047TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001048 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001049 // This test verifies that setting RtpParameters succeeds only if
1050 // the structure contains exactly one encoding.
1051 // TODO(skvlad): Update this test when we start supporting setting parameters
1052 // for each encoding individually.
1053
1054 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001055 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001056 // Two or more encodings should result in failure.
1057 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001058 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001059 // Zero encodings should also fail.
1060 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001061 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001062}
1063
1064// Changing the SSRC through RtpParameters is not allowed.
1065TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1066 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001067 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001068 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001070}
1071
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001072// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001073// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1075 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001076 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001077 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001078 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001079 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080 ASSERT_EQ(1u, parameters.encodings.size());
1081 ASSERT_TRUE(parameters.encodings[0].active);
1082 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1084 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085
1086 // Now change it back to active and verify we resume sending.
1087 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001088 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1089 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001090}
1091
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001092// Test that SetRtpSendParameters configures the correct encoding channel for
1093// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001094TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1095 SetupForMultiSendStream();
1096 // Create send streams.
1097 for (uint32_t ssrc : kSsrcs4) {
1098 EXPECT_TRUE(
1099 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1100 }
1101 // Configure one stream to be limited by the stream config, another to be
1102 // limited by the global max, and the third one with no per-stream limit
1103 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001104 SetGlobalMaxBitrate(kOpusCodec, 32000);
1105 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1106 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001107 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1108
ossu20a4b3f2017-04-27 02:08:52 -07001109 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1110 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1111 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001112
1113 // Remove the global cap; the streams should switch to their respective
1114 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001115 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001116 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1117 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1118 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001119}
1120
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001121// Test that GetRtpSendParameters returns the currently configured codecs.
1122TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001123 EXPECT_TRUE(SetupSendStream());
1124 cricket::AudioSendParameters parameters;
1125 parameters.codecs.push_back(kIsacCodec);
1126 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001127 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001128
solenberg2100c0b2017-03-01 11:29:29 -08001129 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001130 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001131 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1132 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001133}
1134
deadbeefcb443432016-12-12 11:12:36 -08001135// Test that GetRtpSendParameters returns an SSRC.
1136TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1137 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001138 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001139 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001140 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001141}
1142
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001144TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001145 EXPECT_TRUE(SetupSendStream());
1146 cricket::AudioSendParameters parameters;
1147 parameters.codecs.push_back(kIsacCodec);
1148 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001149 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150
solenberg2100c0b2017-03-01 11:29:29 -08001151 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152
1153 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001154 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001156 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001157 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1158 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001159}
1160
minyuececec102017-03-27 13:04:25 -07001161// Test that max_bitrate_bps in send stream config gets updated correctly when
1162// SetRtpSendParameters is called.
1163TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1164 webrtc::test::ScopedFieldTrials override_field_trials(
1165 "WebRTC-Audio-SendSideBwe/Enabled/");
1166 EXPECT_TRUE(SetupSendStream());
1167 cricket::AudioSendParameters send_parameters;
1168 send_parameters.codecs.push_back(kOpusCodec);
1169 SetSendParameters(send_parameters);
1170
1171 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1172 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1173 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1174
1175 constexpr int kMaxBitrateBps = 6000;
1176 rtp_parameters.encodings[0].max_bitrate_bps =
1177 rtc::Optional<int>(kMaxBitrateBps);
1178 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1179
1180 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1181 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1182}
1183
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001184// Test that GetRtpReceiveParameters returns the currently configured codecs.
1185TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1186 EXPECT_TRUE(SetupRecvStream());
1187 cricket::AudioRecvParameters parameters;
1188 parameters.codecs.push_back(kIsacCodec);
1189 parameters.codecs.push_back(kPcmuCodec);
1190 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1191
1192 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001193 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001194 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1195 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1196 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1197}
1198
deadbeefcb443432016-12-12 11:12:36 -08001199// Test that GetRtpReceiveParameters returns an SSRC.
1200TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1201 EXPECT_TRUE(SetupRecvStream());
1202 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001203 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001204 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001205 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001206}
1207
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001208// Test that if we set/get parameters multiple times, we get the same results.
1209TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1210 EXPECT_TRUE(SetupRecvStream());
1211 cricket::AudioRecvParameters parameters;
1212 parameters.codecs.push_back(kIsacCodec);
1213 parameters.codecs.push_back(kPcmuCodec);
1214 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1215
1216 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001217 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001218
1219 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001220 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221
1222 // ... And this shouldn't change the params returned by
1223 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001224 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1225 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001226}
1227
deadbeef3bc15102017-04-20 19:25:07 -07001228// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1229// aren't signaled. It should return an empty "RtpEncodingParameters" when
1230// configured to receive an unsignaled stream and no packets have been received
1231// yet, and start returning the SSRC once a packet has been received.
1232TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1233 ASSERT_TRUE(SetupChannel());
1234 // Call necessary methods to configure receiving a default stream as
1235 // soon as it arrives.
1236 cricket::AudioRecvParameters parameters;
1237 parameters.codecs.push_back(kIsacCodec);
1238 parameters.codecs.push_back(kPcmuCodec);
1239 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1240
1241 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1242 // stream. Should return nothing.
1243 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1244
1245 // Set a sink for an unsignaled stream.
1246 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1247 // Value of "0" means "unsignaled stream".
1248 channel_->SetRawAudioSink(0, std::move(fake_sink));
1249
1250 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1251 // in this method means "unsignaled stream".
1252 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1253 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1254 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1255
1256 // Receive PCMU packet (SSRC=1).
1257 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1258
1259 // The |ssrc| member should still be unset.
1260 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1261 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1262 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1263}
1264
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001265// Test that we apply codecs properly.
1266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001267 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001268 cricket::AudioSendParameters parameters;
1269 parameters.codecs.push_back(kIsacCodec);
1270 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001271 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001272 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001273 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001274 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001275 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1276 EXPECT_EQ(96, send_codec_spec.payload_type);
1277 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1278 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1279 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1280 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001281 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001282}
1283
ossu20a4b3f2017-04-27 02:08:52 -07001284// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1285// AudioSendStream.
1286TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001287 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001288 cricket::AudioSendParameters parameters;
1289 parameters.codecs.push_back(kIsacCodec);
1290 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001291 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001292 parameters.codecs[0].id = 96;
1293 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001294 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001295 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001296 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001297 // Calling SetSendCodec again with same codec which is already set.
1298 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001299 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001300 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001301}
1302
ossu20a4b3f2017-04-27 02:08:52 -07001303// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1304// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001305
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001306// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001308 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001309 cricket::AudioSendParameters parameters;
1310 parameters.codecs.push_back(kOpusCodec);
1311 parameters.codecs[0].bitrate = 0;
1312 parameters.codecs[0].clockrate = 50000;
1313 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001314}
1315
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001316// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001317TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001318 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001319 cricket::AudioSendParameters parameters;
1320 parameters.codecs.push_back(kOpusCodec);
1321 parameters.codecs[0].bitrate = 0;
1322 parameters.codecs[0].channels = 0;
1323 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324}
1325
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001326// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001328 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001329 cricket::AudioSendParameters parameters;
1330 parameters.codecs.push_back(kOpusCodec);
1331 parameters.codecs[0].bitrate = 0;
1332 parameters.codecs[0].channels = 0;
1333 parameters.codecs[0].params["stereo"] = "1";
1334 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
1337// Test that if channel is 1 for opus and there's no stereo, we fail.
1338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].channels = 1;
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
1347// Test that if channel is 1 for opus and stereo=0, we fail.
1348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
1353 parameters.codecs[0].channels = 1;
1354 parameters.codecs[0].params["stereo"] = "0";
1355 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
1358// Test that if channel is 1 for opus and stereo=1, we fail.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001360 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 cricket::AudioSendParameters parameters;
1362 parameters.codecs.push_back(kOpusCodec);
1363 parameters.codecs[0].bitrate = 0;
1364 parameters.codecs[0].channels = 1;
1365 parameters.codecs[0].params["stereo"] = "1";
1366 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001367}
1368
ossu20a4b3f2017-04-27 02:08:52 -07001369// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001375 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001376 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377}
1378
ossu20a4b3f2017-04-27 02:08:52 -07001379// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001380TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001381 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 0;
1385 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001386 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001387 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388}
1389
ossu20a4b3f2017-04-27 02:08:52 -07001390// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001391TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001392 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 cricket::AudioSendParameters parameters;
1394 parameters.codecs.push_back(kOpusCodec);
1395 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001396 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001398 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001399 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001400
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001402 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001403 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001404}
1405
ossu20a4b3f2017-04-27 02:08:52 -07001406// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001408 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 cricket::AudioSendParameters parameters;
1410 parameters.codecs.push_back(kOpusCodec);
1411 parameters.codecs[0].bitrate = 0;
1412 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001414 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
ossu20a4b3f2017-04-27 02:08:52 -07001417// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001423 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001427
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001430 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001431}
1432
ossu20a4b3f2017-04-27 02:08:52 -07001433// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kOpusCodec);
1438 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1441 EXPECT_EQ(111, spec.payload_type);
1442 EXPECT_EQ(96000, spec.target_bitrate_bps);
1443 EXPECT_EQ("opus", spec.format.name);
1444 EXPECT_EQ(2, spec.format.num_channels);
1445 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
ossu20a4b3f2017-04-27 02:08:52 -07001448// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].bitrate = 30000;
1454 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001455 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001456 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457}
1458
ossu20a4b3f2017-04-27 02:08:52 -07001459// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001461 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 cricket::AudioSendParameters parameters;
1463 parameters.codecs.push_back(kOpusCodec);
1464 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001465 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001466 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467}
1468
ossu20a4b3f2017-04-27 02:08:52 -07001469// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 30000;
1475 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001478}
1479
stefan13f1a0a2016-11-30 07:22:58 -08001480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1481 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1482 200000);
1483}
1484
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1486 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1487}
1488
1489TEST_F(WebRtcVoiceEngineTestFake,
1490 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1491 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1492}
1493
1494TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1495 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1496}
1497
1498TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001499 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001500 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1501 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001502 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001503 SetSendParameters(send_parameters_);
1504 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1505 << "Setting max bitrate should keep previous min bitrate.";
1506 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1507 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001508 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001509}
1510
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001511// Test that we can enable NACK with opus as caller.
1512TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001513 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001514 cricket::AudioSendParameters parameters;
1515 parameters.codecs.push_back(kOpusCodec);
1516 parameters.codecs[0].AddFeedbackParam(
1517 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1518 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001519 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001520 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522}
1523
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001524// Test that we can enable NACK with opus as callee.
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001526 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 cricket::AudioSendParameters parameters;
1528 parameters.codecs.push_back(kOpusCodec);
1529 parameters.codecs[0].AddFeedbackParam(
1530 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1531 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001532 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001534 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001535 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001536
1537 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001538 cricket::StreamParams::CreateLegacy(kSsrcX)));
1539 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001540}
1541
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542// Test that we can enable NACK on receive streams.
1543TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001544 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001545 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].AddFeedbackParam(
1549 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1550 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1552 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1555 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556}
1557
1558// Test that we can disable NACK.
1559TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001560 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001561 cricket::AudioSendParameters parameters;
1562 parameters.codecs.push_back(kOpusCodec);
1563 parameters.codecs[0].AddFeedbackParam(
1564 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1565 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001566 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001567 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001568
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 parameters.codecs.clear();
1570 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001571 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573}
1574
1575// Test that we can disable NACK on receive streams.
1576TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001577 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001578 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001579 cricket::AudioSendParameters parameters;
1580 parameters.codecs.push_back(kOpusCodec);
1581 parameters.codecs[0].AddFeedbackParam(
1582 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1583 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001584 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1586 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 parameters.codecs.clear();
1589 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1592 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
1595// Test that NACK is enabled on a new receive stream.
1596TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kIsacCodec);
1600 parameters.codecs.push_back(kCn16000Codec);
1601 parameters.codecs[0].AddFeedbackParam(
1602 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1603 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001605 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
solenberg2100c0b2017-03-01 11:29:29 -08001607 EXPECT_TRUE(AddRecvStream(kSsrcY));
1608 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1609 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1610 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
stefanba4c0e42016-02-04 04:12:24 -08001613TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001614 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001615 cricket::AudioSendParameters send_parameters;
1616 send_parameters.codecs.push_back(kOpusCodec);
1617 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001618 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001619
1620 cricket::AudioRecvParameters recv_parameters;
1621 recv_parameters.codecs.push_back(kIsacCodec);
1622 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_TRUE(AddRecvStream(kSsrcX));
1624 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001625 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001626 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001627
ossudedfd282016-06-14 07:12:39 -07001628 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001630 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001631 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001632 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001633}
1634
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001635// Test that we can switch back and forth between Opus and ISAC with CN.
1636TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001637 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001638
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001639 cricket::AudioSendParameters opus_parameters;
1640 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001642 {
ossu20a4b3f2017-04-27 02:08:52 -07001643 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1644 EXPECT_EQ(111, spec.payload_type);
1645 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001646 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001647
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001648 cricket::AudioSendParameters isac_parameters;
1649 isac_parameters.codecs.push_back(kIsacCodec);
1650 isac_parameters.codecs.push_back(kCn16000Codec);
1651 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001652 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001653 {
ossu20a4b3f2017-04-27 02:08:52 -07001654 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1655 EXPECT_EQ(103, spec.payload_type);
1656 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001657 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001658
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001660 {
ossu20a4b3f2017-04-27 02:08:52 -07001661 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1662 EXPECT_EQ(111, spec.payload_type);
1663 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001664 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665}
1666
1667// Test that we handle various ways of specifying bitrate.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001670 cricket::AudioSendParameters parameters;
1671 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(103, spec.payload_type);
1676 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1677 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001678 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001682 {
ossu20a4b3f2017-04-27 02:08:52 -07001683 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1684 EXPECT_EQ(103, spec.payload_type);
1685 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1686 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001687 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001689 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001690 {
ossu20a4b3f2017-04-27 02:08:52 -07001691 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1692 EXPECT_EQ(103, spec.payload_type);
1693 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1694 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001695 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001697 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(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(0, spec.payload_type);
1702 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1703 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001704 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001706 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001708 {
ossu20a4b3f2017-04-27 02:08:52 -07001709 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1710 EXPECT_EQ(0, spec.payload_type);
1711 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1712 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001713 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001715 parameters.codecs[0] = kOpusCodec;
1716 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001717 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001718 {
ossu20a4b3f2017-04-27 02:08:52 -07001719 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1720 EXPECT_EQ(111, spec.payload_type);
1721 EXPECT_STREQ("opus", spec.format.name.c_str());
1722 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001723 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724}
1725
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001726// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001729 cricket::AudioSendParameters parameters;
1730 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001731}
1732
1733// Test that we can set send codecs even with telephone-event codec as the first
1734// one on the list.
1735TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001736 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001738 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 parameters.codecs.push_back(kIsacCodec);
1740 parameters.codecs.push_back(kPcmuCodec);
1741 parameters.codecs[0].id = 98; // DTMF
1742 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001744 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1745 EXPECT_EQ(96, spec.payload_type);
1746 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001747 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001748}
1749
solenberg31642aa2016-03-14 08:00:37 -07001750// Test that payload type range is limited for telephone-event codec.
1751TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001752 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001753 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001754 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001755 parameters.codecs.push_back(kIsacCodec);
1756 parameters.codecs[0].id = 0; // DTMF
1757 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001758 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001759 EXPECT_TRUE(channel_->CanInsertDtmf());
1760 parameters.codecs[0].id = 128; // DTMF
1761 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1762 EXPECT_FALSE(channel_->CanInsertDtmf());
1763 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001765 EXPECT_TRUE(channel_->CanInsertDtmf());
1766 parameters.codecs[0].id = -1; // DTMF
1767 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1768 EXPECT_FALSE(channel_->CanInsertDtmf());
1769}
1770
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001771// Test that we can set send codecs even with CN codec as the first
1772// one on the list.
1773TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001774 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 cricket::AudioSendParameters parameters;
1776 parameters.codecs.push_back(kCn16000Codec);
1777 parameters.codecs.push_back(kIsacCodec);
1778 parameters.codecs.push_back(kPcmuCodec);
1779 parameters.codecs[0].id = 98; // wideband CN
1780 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(96, send_codec_spec.payload_type);
1784 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001785 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786}
1787
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001788// Test that we set VAD and DTMF types correctly as caller.
1789TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001790 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 cricket::AudioSendParameters parameters;
1792 parameters.codecs.push_back(kIsacCodec);
1793 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs.push_back(kCn16000Codec);
1796 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001797 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001798 parameters.codecs[0].id = 96;
1799 parameters.codecs[2].id = 97; // wideband CN
1800 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001801 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_EQ(96, send_codec_spec.payload_type);
1804 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1805 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001806 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001807 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808}
1809
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001810// Test that we set VAD and DTMF types correctly as callee.
1811TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 cricket::AudioSendParameters parameters;
1814 parameters.codecs.push_back(kIsacCodec);
1815 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001816 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001817 parameters.codecs.push_back(kCn16000Codec);
1818 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001819 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001820 parameters.codecs[0].id = 96;
1821 parameters.codecs[2].id = 97; // wideband CN
1822 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001823 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001824 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001825 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001826
ossu20a4b3f2017-04-27 02:08:52 -07001827 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1828 EXPECT_EQ(96, send_codec_spec.payload_type);
1829 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1830 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001831 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001832 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001833}
1834
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835// Test that we only apply VAD if we have a CN codec that matches the
1836// send codec clockrate.
1837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 parameters.codecs.push_back(kIsacCodec);
1842 parameters.codecs.push_back(kCn16000Codec);
1843 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001845 {
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1848 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001849 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001850 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001851 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001854 {
ossu20a4b3f2017-04-27 02:08:52 -07001855 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1856 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1857 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001858 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001861 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001862 {
ossu20a4b3f2017-04-27 02:08:52 -07001863 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1864 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1865 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001866 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001867 }
Brave Yao5225dd82015-03-26 07:39:19 +08001868 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001870 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001871 {
ossu20a4b3f2017-04-27 02:08:52 -07001872 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1873 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1874 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001875 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876}
1877
1878// Test that we perform case-insensitive matching of codec names.
1879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 cricket::AudioSendParameters parameters;
1882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs.push_back(kPcmuCodec);
1884 parameters.codecs.push_back(kCn16000Codec);
1885 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001886 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 parameters.codecs[0].name = "iSaC";
1888 parameters.codecs[0].id = 96;
1889 parameters.codecs[2].id = 97; // wideband CN
1890 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001892 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1893 EXPECT_EQ(96, send_codec_spec.payload_type);
1894 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1895 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001897 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001898}
1899
stefanba4c0e42016-02-04 04:12:24 -08001900class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1901 public:
1902 WebRtcVoiceEngineWithSendSideBweTest()
1903 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1904};
1905
1906TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1907 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001908 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001909 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001910 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1911 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1912 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001913 extension.id);
1914 return;
1915 }
1916 }
1917 FAIL() << "Transport sequence number extension not in header-extension list.";
1918}
1919
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001920// Test support for audio level header extension.
1921TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001922 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001923}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001924TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001925 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001926}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001927
solenbergd4adce42016-11-17 06:26:52 -08001928// Test support for transport sequence number header extension.
1929TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1930 TestSetSendRtpHeaderExtensions(
1931 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001932}
solenbergd4adce42016-11-17 06:26:52 -08001933TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1934 TestSetRecvRtpHeaderExtensions(
1935 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001936}
1937
solenberg1ac56142015-10-13 03:58:19 -07001938// Test that we can create a channel and start sending on it.
1939TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001940 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(send_parameters_);
1942 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001943 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001944 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001945 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001946}
1947
1948// Test that a channel will send if and only if it has a source and is enabled
1949// for sending.
1950TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001951 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001952 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001953 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001954 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001955 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1956 SetAudioSend(kSsrcX, true, &fake_source_);
1957 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1958 SetAudioSend(kSsrcX, true, nullptr);
1959 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001960}
1961
solenberg94218532016-06-16 10:53:22 -07001962// Test that a channel is muted/unmuted.
1963TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1964 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001965 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001966 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1967 SetAudioSend(kSsrcX, true, nullptr);
1968 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1969 SetAudioSend(kSsrcX, false, nullptr);
1970 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001971}
1972
solenberg6d6e7c52016-04-13 09:07:30 -07001973// Test that SetSendParameters() does not alter a stream's send state.
1974TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1975 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001977
1978 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001979 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001980 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001981
1982 // Changing RTP header extensions will recreate the AudioSendStream.
1983 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001984 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001987
1988 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001989 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001990 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001991
1992 // Changing RTP header extensions will recreate the AudioSendStream.
1993 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001994 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996}
1997
solenberg1ac56142015-10-13 03:58:19 -07001998// Test that we can create a channel and start playing out on it.
1999TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002000 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002001 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002002 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002003 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002004 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002006}
2007
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002008// Test that we can add and remove send streams.
2009TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2010 SetupForMultiSendStream();
2011
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002012 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002013 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014
solenbergc96df772015-10-21 13:01:53 -07002015 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002016 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002017 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002018 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002020 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 }
tfarina5237aaf2015-11-10 23:44:30 -08002022 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023
solenbergc96df772015-10-21 13:01:53 -07002024 // Delete the send streams.
2025 for (uint32_t ssrc : kSsrcs4) {
2026 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002027 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002028 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029 }
solenbergc96df772015-10-21 13:01:53 -07002030 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031}
2032
2033// Test SetSendCodecs correctly configure the codecs in all send streams.
2034TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2035 SetupForMultiSendStream();
2036
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002038 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002040 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041 }
2042
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002043 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002045 parameters.codecs.push_back(kIsacCodec);
2046 parameters.codecs.push_back(kCn16000Codec);
2047 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002048 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049
2050 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002051 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002052 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2053 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002054 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2055 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2056 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002057 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 }
2059
minyue7a973442016-10-20 03:27:12 -07002060 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002061 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002063 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002064 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2065 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002066 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2067 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2068 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 }
2070}
2071
2072// Test we can SetSend on all send streams correctly.
2073TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2074 SetupForMultiSendStream();
2075
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002076 // Create the send channels and they should be a "not sending" date.
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)));
solenberg059fb442016-10-26 05:12:24 -07002080 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002081 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002082 }
2083
2084 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002085 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002086 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002088 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
2090
2091 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002092 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002093 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002095 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 }
2097}
2098
2099// Test we can set the correct statistics on all send streams.
2100TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2101 SetupForMultiSendStream();
2102
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002104 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002106 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 }
solenberg85a04962015-10-27 03:35:21 -07002108
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002109 // Create a receive stream to check that none of the send streams end up in
2110 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002112
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002114 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002115 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002116 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117
solenberg85a04962015-10-27 03:35:21 -07002118 // Check stats for the added streams.
2119 {
2120 cricket::VoiceMediaInfo info;
2121 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122
solenberg85a04962015-10-27 03:35:21 -07002123 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002124 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002125 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002126 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002127 }
hbos1acfbd22016-11-17 23:43:29 -08002128 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002129
2130 // We have added one receive stream. We should see empty stats.
2131 EXPECT_EQ(info.receivers.size(), 1u);
2132 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 }
solenberg1ac56142015-10-13 03:58:19 -07002134
solenberg2100c0b2017-03-01 11:29:29 -08002135 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002136 {
2137 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002138 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002139 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002140 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002141 EXPECT_EQ(0u, info.receivers.size());
2142 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002143
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002144 // Deliver a new packet - a default receive stream should be created and we
2145 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002146 {
2147 cricket::VoiceMediaInfo info;
2148 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2149 SetAudioReceiveStreamStats();
2150 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002151 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002152 EXPECT_EQ(1u, info.receivers.size());
2153 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002154 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002155 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156}
2157
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158// Test that we can add and remove receive streams, and do proper send/playout.
2159// We can receive on multiple streams while sending one stream.
2160TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002161 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002162
solenberg1ac56142015-10-13 03:58:19 -07002163 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002164 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002165 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166
solenberg1ac56142015-10-13 03:58:19 -07002167 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002169 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002170 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171
solenberg1ac56142015-10-13 03:58:19 -07002172 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002173 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002174
2175 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002176 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2177 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2178 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002179
2180 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002181 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183
2184 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002185 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002186 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2187 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188
aleloi84ef6152016-08-04 05:28:21 -07002189 // Restart playout and make sure recv streams are played out.
2190 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002191 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2192 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
aleloi84ef6152016-08-04 05:28:21 -07002194 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002195 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2196 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002197}
2198
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002199// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002200// and start sending on it.
2201TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002202 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002203 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2204 EXPECT_CALL(apm_gc_,
2205 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002206 SetSendParameters(send_parameters_);
2207 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002208 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002209 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002210 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002211}
2212
wu@webrtc.org97077a32013-10-25 21:18:33 +00002213TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002214 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002215 EXPECT_CALL(adm_,
2216 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002217 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2218 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002219 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2220 send_parameters_.options.tx_agc_digital_compression_gain =
2221 rtc::Optional<uint16_t>(9);
2222 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2223 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002224 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2225 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2226 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002227 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002228
2229 // Check interaction with adjust_agc_delta. Both should be respected, for
2230 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002231 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002232 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002233 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002234}
2235
wu@webrtc.org97077a32013-10-25 21:18:33 +00002236TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002237 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002238 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2239 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002240 send_parameters_.options.recording_sample_rate =
2241 rtc::Optional<uint32_t>(48000);
2242 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002243 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002244}
2245
minyue6b825df2016-10-31 04:08:32 -07002246TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2247 EXPECT_TRUE(SetupSendStream());
2248 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2249 send_parameters_.options.audio_network_adaptor_config =
2250 rtc::Optional<std::string>("1234");
2251 SetSendParameters(send_parameters_);
2252 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002253 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002254}
2255
2256TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2257 EXPECT_TRUE(SetupSendStream());
2258 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2259 send_parameters_.options.audio_network_adaptor_config =
2260 rtc::Optional<std::string>("1234");
2261 SetSendParameters(send_parameters_);
2262 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002263 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002264 cricket::AudioOptions options;
2265 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002266 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002267 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002268}
2269
2270TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2271 EXPECT_TRUE(SetupSendStream());
2272 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2273 send_parameters_.options.audio_network_adaptor_config =
2274 rtc::Optional<std::string>("1234");
2275 SetSendParameters(send_parameters_);
2276 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002277 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002278 const int initial_num = call_.GetNumCreatedSendStreams();
2279 cricket::AudioOptions options;
2280 options.audio_network_adaptor = rtc::Optional<bool>();
2281 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2282 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002283 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002284 // AudioSendStream not expected to be recreated.
2285 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2286 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002287 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002288}
2289
michaelt6672b262017-01-11 10:17:59 -08002290class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2291 : public WebRtcVoiceEngineTestFake {
2292 public:
2293 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2294 : WebRtcVoiceEngineTestFake(
2295 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2296 "Enabled/") {}
2297};
2298
2299TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2300 EXPECT_TRUE(SetupSendStream());
2301 cricket::AudioSendParameters parameters;
2302 parameters.codecs.push_back(kOpusCodec);
2303 SetSendParameters(parameters);
2304 const int initial_num = call_.GetNumCreatedSendStreams();
2305 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2306
2307 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2308 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002309 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2310 constexpr int kMinOverheadBps =
2311 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002312
2313 constexpr int kOpusMinBitrateBps = 6000;
2314 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002315 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002316 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002317 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002318 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002319
2320 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2321 parameters.options.audio_network_adaptor_config =
2322 rtc::Optional<std::string>("1234");
2323 SetSendParameters(parameters);
2324
ossu11bfc532017-02-16 05:37:06 -08002325 constexpr int kMinOverheadWithAnaBps =
2326 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002327
2328 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002329 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002330
minyuececec102017-03-27 13:04:25 -07002331 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002332 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002333}
2334
minyuececec102017-03-27 13:04:25 -07002335// This test is similar to
2336// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2337// additional field trial.
2338TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2339 SetRtpSendParameterUpdatesMaxBitrate) {
2340 EXPECT_TRUE(SetupSendStream());
2341 cricket::AudioSendParameters send_parameters;
2342 send_parameters.codecs.push_back(kOpusCodec);
2343 SetSendParameters(send_parameters);
2344
2345 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2346 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2347 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2348
2349 constexpr int kMaxBitrateBps = 6000;
2350 rtp_parameters.encodings[0].max_bitrate_bps =
2351 rtc::Optional<int>(kMaxBitrateBps);
2352 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2353
2354 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2355#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2356 constexpr int kMinOverhead = 3333;
2357#else
2358 constexpr int kMinOverhead = 6666;
2359#endif
2360 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2361}
2362
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002364// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002366 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002367 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368}
2369
2370TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2371 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002372 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002373 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002374 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002375 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002376 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002377 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002378 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002379
solenberg85a04962015-10-27 03:35:21 -07002380 // Check stats for the added streams.
2381 {
2382 cricket::VoiceMediaInfo info;
2383 EXPECT_EQ(true, channel_->GetStats(&info));
2384
2385 // We have added one send stream. We should see the stats we've set.
2386 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002387 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002388 // We have added one receive stream. We should see empty stats.
2389 EXPECT_EQ(info.receivers.size(), 1u);
2390 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2391 }
solenberg1ac56142015-10-13 03:58:19 -07002392
solenberg566ef242015-11-06 15:34:49 -08002393 // Start sending - this affects some reported stats.
2394 {
2395 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002396 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002397 EXPECT_EQ(true, channel_->GetStats(&info));
2398 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002399 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002400 }
2401
solenberg2100c0b2017-03-01 11:29:29 -08002402 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002403 {
2404 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002405 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002406 EXPECT_EQ(true, channel_->GetStats(&info));
2407 EXPECT_EQ(1u, info.senders.size());
2408 EXPECT_EQ(0u, info.receivers.size());
2409 }
solenberg1ac56142015-10-13 03:58:19 -07002410
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002411 // Deliver a new packet - a default receive stream should be created and we
2412 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002413 {
2414 cricket::VoiceMediaInfo info;
2415 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2416 SetAudioReceiveStreamStats();
2417 EXPECT_EQ(true, channel_->GetStats(&info));
2418 EXPECT_EQ(1u, info.senders.size());
2419 EXPECT_EQ(1u, info.receivers.size());
2420 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002421 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002422 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423}
2424
2425// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002426// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002428 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002429 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2430 EXPECT_TRUE(AddRecvStream(kSsrcY));
2431 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002432}
2433
2434// Test that the local SSRC is the same on sending and receiving channels if the
2435// receive channel is created before the send channel.
2436TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002437 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002438 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002440 cricket::StreamParams::CreateLegacy(kSsrcX)));
2441 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2442 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443}
2444
2445// Test that we can properly receive packets.
2446TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002448 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002450
2451 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2452 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453}
2454
2455// Test that we can properly receive packets on multiple streams.
2456TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002457 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002458 const uint32_t ssrc1 = 1;
2459 const uint32_t ssrc2 = 2;
2460 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002461 EXPECT_TRUE(AddRecvStream(ssrc1));
2462 EXPECT_TRUE(AddRecvStream(ssrc2));
2463 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002465 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002466 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002468 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 }
mflodman3d7db262016-04-29 00:57:13 -07002470
2471 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2472 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2473 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2474
2475 EXPECT_EQ(s1.received_packets(), 0);
2476 EXPECT_EQ(s2.received_packets(), 0);
2477 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002478
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002480 EXPECT_EQ(s1.received_packets(), 0);
2481 EXPECT_EQ(s2.received_packets(), 0);
2482 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002483
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002485 EXPECT_EQ(s1.received_packets(), 1);
2486 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2487 EXPECT_EQ(s2.received_packets(), 0);
2488 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002489
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002491 EXPECT_EQ(s1.received_packets(), 1);
2492 EXPECT_EQ(s2.received_packets(), 1);
2493 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2494 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002495
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_EQ(s1.received_packets(), 1);
2498 EXPECT_EQ(s2.received_packets(), 1);
2499 EXPECT_EQ(s3.received_packets(), 1);
2500 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002501
mflodman3d7db262016-04-29 00:57:13 -07002502 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2503 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2504 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505}
2506
solenberg2100c0b2017-03-01 11:29:29 -08002507// Test that receiving on an unsignaled stream works (a stream is created).
2508TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002509 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002510 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2511
solenberg7e63ef02015-11-20 00:19:43 -08002512 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002513
2514 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002515 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2516 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002517}
2518
solenberg2100c0b2017-03-01 11:29:29 -08002519// Test that receiving N unsignaled stream works (streams will be created), and
2520// that packets are forwarded to them all.
2521TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002522 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002523 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002524 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2525
solenberg2100c0b2017-03-01 11:29:29 -08002526 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002527 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002528 rtc::SetBE32(&packet[8], ssrc);
2529 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002530
solenberg2100c0b2017-03-01 11:29:29 -08002531 // Verify we have one new stream for each loop iteration.
2532 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002533 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2534 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002535 }
mflodman3d7db262016-04-29 00:57:13 -07002536
solenberg2100c0b2017-03-01 11:29:29 -08002537 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002538 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002539 rtc::SetBE32(&packet[8], ssrc);
2540 DeliverPacket(packet, sizeof(packet));
2541
solenbergebb349d2017-03-13 05:46:15 -07002542 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002543 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2544 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2545 }
2546
2547 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2548 constexpr uint32_t kAnotherSsrc = 667;
2549 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002550 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002551
2552 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002553 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002554 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002555 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002556 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2557 EXPECT_EQ(2, streams[i]->received_packets());
2558 }
2559 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2560 EXPECT_EQ(1, streams[i]->received_packets());
2561 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002562 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002563}
2564
solenberg2100c0b2017-03-01 11:29:29 -08002565// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002566// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002567TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002568 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002569 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002570 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2571
2572 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002573 const uint32_t signaled_ssrc = 1;
2574 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002575 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002576 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002577 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2578 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002579 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002580
2581 // Note that the first unknown SSRC cannot be 0, because we only support
2582 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002583 const uint32_t unsignaled_ssrc = 7011;
2584 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002585 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002586 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2587 packet, sizeof(packet)));
2588 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2589
2590 DeliverPacket(packet, sizeof(packet));
2591 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2592
2593 rtc::SetBE32(&packet[8], signaled_ssrc);
2594 DeliverPacket(packet, sizeof(packet));
2595 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2596 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002597}
2598
solenberg4904fb62017-02-17 12:01:14 -08002599// Two tests to verify that adding a receive stream with the same SSRC as a
2600// previously added unsignaled stream will only recreate underlying stream
2601// objects if the stream parameters have changed.
2602TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2603 EXPECT_TRUE(SetupChannel());
2604
2605 // Spawn unsignaled stream with SSRC=1.
2606 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2607 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2608 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2609 sizeof(kPcmuFrame)));
2610
2611 // Verify that the underlying stream object in Call is not recreated when a
2612 // stream with SSRC=1 is added.
2613 const auto& streams = call_.GetAudioReceiveStreams();
2614 EXPECT_EQ(1, streams.size());
2615 int audio_receive_stream_id = streams.front()->id();
2616 EXPECT_TRUE(AddRecvStream(1));
2617 EXPECT_EQ(1, streams.size());
2618 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2619}
2620
2621TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2622 EXPECT_TRUE(SetupChannel());
2623
2624 // Spawn unsignaled stream with SSRC=1.
2625 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2626 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2627 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2628 sizeof(kPcmuFrame)));
2629
2630 // Verify that the underlying stream object in Call *is* recreated when a
2631 // stream with SSRC=1 is added, and which has changed stream parameters.
2632 const auto& streams = call_.GetAudioReceiveStreams();
2633 EXPECT_EQ(1, streams.size());
2634 int audio_receive_stream_id = streams.front()->id();
2635 cricket::StreamParams stream_params;
2636 stream_params.ssrcs.push_back(1);
2637 stream_params.sync_label = "sync_label";
2638 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2639 EXPECT_EQ(1, streams.size());
2640 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2641}
2642
solenberg0a617e22015-10-20 15:49:38 -07002643// Test that we properly handle failures to add a receive stream.
2644TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002645 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002646 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002647 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648}
2649
solenberg0a617e22015-10-20 15:49:38 -07002650// Test that we properly handle failures to add a send stream.
2651TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002653 voe_.set_fail_create_channel(true);
2654 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2655}
2656
solenberg1ac56142015-10-13 03:58:19 -07002657// Test that AddRecvStream creates new stream.
2658TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002659 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002660 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002661 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002662 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663}
2664
2665// Test that after adding a recv stream, we do not decode more codecs than
2666// those previously passed into SetRecvCodecs.
2667TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002668 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002669 cricket::AudioRecvParameters parameters;
2670 parameters.codecs.push_back(kIsacCodec);
2671 parameters.codecs.push_back(kPcmuCodec);
2672 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002673 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002674 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2675 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2676 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002677}
2678
2679// Test that we properly clean up any streams that were added, even if
2680// not explicitly removed.
2681TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002682 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002683 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002684 EXPECT_TRUE(AddRecvStream(1));
2685 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002686 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2687 delete channel_;
2688 channel_ = NULL;
2689 EXPECT_EQ(0, voe_.GetNumChannels());
2690}
2691
wu@webrtc.org78187522013-10-07 23:32:02 +00002692TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002693 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002694 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002695}
2696
2697TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002698 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002699 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002700 // Manually delete channel to simulate a failure.
2701 int channel = voe_.GetLastChannel();
2702 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2703 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002704 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002705 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002706 EXPECT_NE(channel, new_channel);
2707 // The last created channel is deleted too.
2708 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002709}
2710
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002711// Test the InsertDtmf on default send stream as caller.
2712TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002713 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714}
2715
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002716// Test the InsertDtmf on default send stream as callee
2717TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002718 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002719}
2720
2721// Test the InsertDtmf on specified send stream as caller.
2722TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002723 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002724}
2725
2726// Test the InsertDtmf on specified send stream as callee.
2727TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002728 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729}
2730
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002732 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002733 EXPECT_CALL(adm_,
2734 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2735 EXPECT_CALL(adm_,
2736 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2737 EXPECT_CALL(adm_,
2738 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002739
solenberg246b8172015-12-08 09:50:23 -08002740 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2741 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742
solenberg246b8172015-12-08 09:50:23 -08002743 // Nothing set in AudioOptions, so everything should be as default.
2744 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002745 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002746 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002747 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2748 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749
2750 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002751 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2752 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002753 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002754 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755
2756 // Turn echo cancellation back on, with settings, and make sure
2757 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002758 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2759 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002760 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002761 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002763 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2764 // control.
solenberg76377c52017-02-21 00:54:31 -08002765 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2766 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002767 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002768 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002769
2770 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002773 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2774 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2775 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002776 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002777
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002778 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002779 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002781 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002783
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002784 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2787 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002789 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002790 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791
2792 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002793 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2794 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2795 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002797 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2798 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002799 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800
2801 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002802 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2803 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2804 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2805 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2806 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2807 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2808 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002809 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2810 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2811 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2812 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002813 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002814 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002815
solenberg1ac56142015-10-13 03:58:19 -07002816 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002817 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2818 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2819 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2820 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2821 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2822 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2823 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002824 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825}
2826
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002828 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002829 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002830 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002831 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002832 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002833 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002834 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002835 EXPECT_CALL(adm_,
2836 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2837 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2838 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002839 webrtc::AudioProcessing::Config apm_config;
2840 EXPECT_CALL(*apm_, GetConfig())
2841 .Times(10)
2842 .WillRepeatedly(ReturnPointee(&apm_config));
2843 EXPECT_CALL(*apm_, ApplyConfig(_))
2844 .Times(10)
2845 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002846 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002847
kwiberg686a8ef2016-02-26 03:00:35 -08002848 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002849 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002850 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002851 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
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())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002854
2855 // Have to add a stream to make SetSend work.
2856 cricket::StreamParams stream1;
2857 stream1.ssrcs.push_back(1);
2858 channel1->AddSendStream(stream1);
2859 cricket::StreamParams stream2;
2860 stream2.ssrcs.push_back(2);
2861 channel2->AddSendStream(stream2);
2862
2863 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002864 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002865 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2866 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2867 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002868 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2869 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2870 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2871 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2872 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002873 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002874 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002875 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002876 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877
2878 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002880 parameters_options_no_ns.options.noise_suppression =
2881 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002882 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2883 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002887 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002888 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002889 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2890 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2891 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002892 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893
2894 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002895 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002896 parameters_options_no_agc.options.auto_gain_control =
2897 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002898 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2899 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002903 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002904 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2905 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2906 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002907 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908
solenberg76377c52017-02-21 00:54:31 -08002909 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2910 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2911 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002914 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2918 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2920 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002921 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922
solenberg76377c52017-02-21 00:54:31 -08002923 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2926 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2927 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002928 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002931 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2932 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002933 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002934 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002935 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002936 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002937 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2938 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2939 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2940 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2941 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002942 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002943 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2944 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2945 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002946 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947}
2948
wu@webrtc.orgde305012013-10-31 15:40:38 +00002949// This test verifies DSCP settings are properly applied on voice media channel.
2950TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002951 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002952 cricket::FakeNetworkInterface network_interface;
2953 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002954 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002955
peahb1c9d1d2017-07-25 15:45:24 -07002956 webrtc::AudioProcessing::Config apm_config;
2957 EXPECT_CALL(*apm_, GetConfig())
2958 .Times(3)
2959 .WillRepeatedly(ReturnPointee(&apm_config));
2960 EXPECT_CALL(*apm_, ApplyConfig(_))
2961 .Times(3)
2962 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002963 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002964
solenbergbc37fc82016-04-04 09:54:44 -07002965 channel.reset(
2966 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002967 channel->SetInterface(&network_interface);
2968 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2969 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2970
2971 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002972 channel.reset(
2973 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002974 channel->SetInterface(&network_interface);
2975 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2976
2977 // Verify that setting the option to false resets the
2978 // DiffServCodePoint.
2979 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002980 channel.reset(
2981 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002982 channel->SetInterface(&network_interface);
2983 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2984 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2985
2986 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002987}
2988
solenberg1ac56142015-10-13 03:58:19 -07002989TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002990 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 cricket::WebRtcVoiceMediaChannel* media_channel =
2992 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002993 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002994 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002995 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002996 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2997 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2998 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002999 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003000 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001}
3002
solenberg1ac56142015-10-13 03:58:19 -07003003TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003004 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003006 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3007 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3008 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003009 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003010 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003011 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3012 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003013 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003014 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003015 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003017}
3018
solenberg4bac9c52015-10-09 02:32:53 -07003019TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003020 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003021 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003023 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003025 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3026 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3027 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003028}
3029
solenberg2100c0b2017-03-01 11:29:29 -08003030TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003031 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003032
3033 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003034 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003035 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3036
3037 // Should remember the volume "2" which will be set on new unsignaled streams,
3038 // and also set the gain to 2 on existing unsignaled streams.
3039 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3040 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3041
3042 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3043 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3044 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3045 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3046 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3047 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3048
3049 // Setting gain with SSRC=0 should affect all unsignaled streams.
3050 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003051 if (kMaxUnsignaledRecvStreams > 1) {
3052 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3053 }
solenberg2100c0b2017-03-01 11:29:29 -08003054 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3055
3056 // Setting gain on an individual stream affects only that.
3057 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003058 if (kMaxUnsignaledRecvStreams > 1) {
3059 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3060 }
solenberg2100c0b2017-03-01 11:29:29 -08003061 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062}
3063
pbos8fc7fa72015-07-15 08:02:58 -07003064TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003065 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003066 const std::string kSyncLabel = "AvSyncLabel";
3067
solenbergff976312016-03-30 23:28:51 -07003068 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003069 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3070 sp.sync_label = kSyncLabel;
3071 // Creating two channels to make sure that sync label is set properly for both
3072 // the default voice channel and following ones.
3073 EXPECT_TRUE(channel_->AddRecvStream(sp));
3074 sp.ssrcs[0] += 1;
3075 EXPECT_TRUE(channel_->AddRecvStream(sp));
3076
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003077 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003078 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003079 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003080 << "SyncGroup should be set based on sync_label";
3081 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003082 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003083 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003084}
3085
solenberg3a941542015-11-16 07:34:50 -08003086// TODO(solenberg): Remove, once recv streams are configured through Call.
3087// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003088TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003089 // Test that setting the header extensions results in the expected state
3090 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003091 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003092 ssrcs.push_back(223);
3093 ssrcs.push_back(224);
3094
solenbergff976312016-03-30 23:28:51 -07003095 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003096 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003097 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003098 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003099 cricket::StreamParams::CreateLegacy(ssrc)));
3100 }
3101
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003102 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003103 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003104 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 EXPECT_NE(nullptr, s);
3106 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3107 }
3108
3109 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003110 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003111 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003112 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003113 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003114 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003115 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003116 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003117 EXPECT_NE(nullptr, s);
3118 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003119 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3120 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003121 for (const auto& s_ext : s_exts) {
3122 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003123 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003124 }
3125 }
3126 }
3127 }
3128
3129 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003130 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003131 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003132 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003133 EXPECT_NE(nullptr, s);
3134 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3135 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003136}
3137
3138TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3139 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003140 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003141 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003142 static const unsigned char kRtcp[] = {
3143 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3144 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3147 };
jbaucheec21bd2016-03-20 06:15:43 -07003148 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003149
solenbergff976312016-03-30 23:28:51 -07003150 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003151 cricket::WebRtcVoiceMediaChannel* media_channel =
3152 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003153 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003154 EXPECT_TRUE(media_channel->AddRecvStream(
3155 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3156
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003157 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003158 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003159 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003160 EXPECT_EQ(0, s->received_packets());
3161 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3162 EXPECT_EQ(1, s->received_packets());
3163 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3164 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003165}
Minyue2013aec2015-05-13 14:14:42 +02003166
solenberg0a617e22015-10-20 15:49:38 -07003167// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003168// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003169TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003170 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003171 EXPECT_TRUE(AddRecvStream(kSsrcY));
3172 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003173 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003174 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3175 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3176 EXPECT_TRUE(AddRecvStream(kSsrcW));
3177 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003178}
3179
solenberg7602aab2016-11-14 11:30:07 -08003180TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3181 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003182 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003183 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003184 cricket::StreamParams::CreateLegacy(kSsrcY)));
3185 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3186 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3187 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003188 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003189 cricket::StreamParams::CreateLegacy(kSsrcW)));
3190 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3191 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003192}
stefan658910c2015-09-03 05:48:32 -07003193
deadbeef884f5852016-01-15 09:20:04 -08003194TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003195 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003196 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3197 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003198
3199 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003200 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3201 EXPECT_TRUE(AddRecvStream(kSsrcX));
3202 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003203
3204 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003205 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3206 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003207
3208 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003209 channel_->SetRawAudioSink(kSsrcX, nullptr);
3210 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003211}
3212
solenberg2100c0b2017-03-01 11:29:29 -08003213TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003214 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003215 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3216 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003217 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3218 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003219
3220 // Should be able to set a default sink even when no stream exists.
3221 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3222
solenberg2100c0b2017-03-01 11:29:29 -08003223 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3224 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003225 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003226 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003227
3228 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003229 channel_->SetRawAudioSink(kSsrc0, nullptr);
3230 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003231
3232 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003233 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3234 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003235
3236 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003237 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003238 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003239 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3240
3241 // Spawn another unsignaled stream - it should be assigned the default sink
3242 // and the previous unsignaled stream should lose it.
3243 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3244 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3245 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3246 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003247 if (kMaxUnsignaledRecvStreams > 1) {
3248 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3249 }
solenberg2100c0b2017-03-01 11:29:29 -08003250 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3251
3252 // Reset the default sink - the second unsignaled stream should lose it.
3253 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003254 if (kMaxUnsignaledRecvStreams > 1) {
3255 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3256 }
solenberg2100c0b2017-03-01 11:29:29 -08003257 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3258
3259 // Try setting the default sink while two streams exists.
3260 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003261 if (kMaxUnsignaledRecvStreams > 1) {
3262 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3263 }
solenberg2100c0b2017-03-01 11:29:29 -08003264 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3265
3266 // Try setting the sink for the first unsignaled stream using its known SSRC.
3267 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003268 if (kMaxUnsignaledRecvStreams > 1) {
3269 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3270 }
solenberg2100c0b2017-03-01 11:29:29 -08003271 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003272 if (kMaxUnsignaledRecvStreams > 1) {
3273 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3274 }
deadbeef884f5852016-01-15 09:20:04 -08003275}
3276
skvlad7a43d252016-03-22 15:32:27 -07003277// Test that, just like the video channel, the voice channel communicates the
3278// network state to the call.
3279TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003280 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003281
3282 EXPECT_EQ(webrtc::kNetworkUp,
3283 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3284 EXPECT_EQ(webrtc::kNetworkUp,
3285 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3286
3287 channel_->OnReadyToSend(false);
3288 EXPECT_EQ(webrtc::kNetworkDown,
3289 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3290 EXPECT_EQ(webrtc::kNetworkUp,
3291 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3292
3293 channel_->OnReadyToSend(true);
3294 EXPECT_EQ(webrtc::kNetworkUp,
3295 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3296 EXPECT_EQ(webrtc::kNetworkUp,
3297 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3298}
3299
aleloi18e0b672016-10-04 02:45:47 -07003300// Test that playout is still started after changing parameters
3301TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3302 SetupRecvStream();
3303 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003304 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003305
3306 // Changing RTP header extensions will recreate the AudioReceiveStream.
3307 cricket::AudioRecvParameters parameters;
3308 parameters.extensions.push_back(
3309 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3310 channel_->SetRecvParameters(parameters);
3311
solenberg2100c0b2017-03-01 11:29:29 -08003312 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003313}
3314
stefan658910c2015-09-03 05:48:32 -07003315// Tests that the library initializes and shuts down properly.
3316TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003317 // If the VoiceEngine wants to gather available codecs early, that's fine but
3318 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003319 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3320 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003321 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003322 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003323 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003324 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003325 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003326 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003327 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003328 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3329 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003330 EXPECT_TRUE(channel != nullptr);
3331 delete channel;
solenbergff976312016-03-30 23:28:51 -07003332}
stefan658910c2015-09-03 05:48:32 -07003333
solenbergff976312016-03-30 23:28:51 -07003334// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003335TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3336 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3337 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3338 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003339 // Return 100ms just in case this function gets called. If we don't,
3340 // we could enter a tight loop since the mock would return 0.
3341 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003342 {
peaha9cc40b2017-06-29 08:32:09 -07003343 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3344 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003345 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003346 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003347 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003348 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003349 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003350 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003351 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003352 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3353 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3354 EXPECT_TRUE(channel != nullptr);
3355 delete channel;
3356 }
stefan658910c2015-09-03 05:48:32 -07003357}
3358
ossu20a4b3f2017-04-27 02:08:52 -07003359// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3360TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003361 // TODO(ossu): Why are the payload types of codecs with non-static payload
3362 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003363 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3364 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003365 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003366 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003367 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003368 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003369 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003370 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3371 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3372 (clockrate == 0 || codec.clockrate == clockrate);
3373 };
3374 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003375 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003376 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003382 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003384 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003385 EXPECT_EQ(126, codec.id);
3386 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3387 // Remove these checks once both send and receive side assigns payload types
3388 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003389 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003390 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003391 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003392 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003393 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003394 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003395 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003396 EXPECT_EQ(111, codec.id);
3397 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3398 EXPECT_EQ("10", codec.params.find("minptime")->second);
3399 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3400 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003401 }
3402 }
stefan658910c2015-09-03 05:48:32 -07003403}
3404
3405// Tests that VoE supports at least 32 channels
3406TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003407 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3408 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003409 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003410 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003411 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003412 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003413 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003414 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003415 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003416
3417 cricket::VoiceMediaChannel* channels[32];
3418 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003419 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003420 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3421 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003422 if (!channel)
3423 break;
stefan658910c2015-09-03 05:48:32 -07003424 channels[num_channels++] = channel;
3425 }
3426
tfarina5237aaf2015-11-10 23:44:30 -08003427 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003428 EXPECT_EQ(expected, num_channels);
3429
3430 while (num_channels > 0) {
3431 delete channels[--num_channels];
3432 }
stefan658910c2015-09-03 05:48:32 -07003433}
3434
3435// Test that we set our preferred codecs properly.
3436TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003437 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3438 // - Check that our builtin codecs are usable by Channel.
3439 // - The codecs provided by the engine is usable by Channel.
3440 // It does not check that the codecs in the RecvParameters are actually
3441 // what we sent in - though it's probably reasonable to expect so, if
3442 // SetRecvParameters returns true.
3443 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003444 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3445 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003446 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003447 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003448 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003449 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003450 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003451 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003452 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003453 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3454 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003455 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003456 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003457 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003458}
ossu9def8002017-02-09 05:14:32 -08003459
3460TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3461 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003462 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3463 {48000, 2, 16000, 10000, 20000}};
3464 spec1.info.allow_comfort_noise = false;
3465 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003466 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003467 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3468 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003469 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003470 specs.push_back(webrtc::AudioCodecSpec{
3471 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3472 {16000, 1, 13300}});
3473 specs.push_back(
3474 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3475 specs.push_back(
3476 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003477
ossueb1fde42017-05-02 06:46:30 -07003478 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3479 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3480 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003481 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003482 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003483 .WillOnce(Return(specs));
3484
peaha9cc40b2017-06-29 08:32:09 -07003485 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3486 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003487 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003488 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003489 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003490 auto codecs = engine.recv_codecs();
3491 EXPECT_EQ(11, codecs.size());
3492
3493 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3494 // check the actual values safely, to provide better test results.
3495 auto get_codec =
3496 [&codecs](size_t index) -> const cricket::AudioCodec& {
3497 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3498 if (codecs.size() > index)
3499 return codecs[index];
3500 return missing_codec;
3501 };
3502
3503 // Ensure the general codecs are generated first and in order.
3504 for (size_t i = 0; i != specs.size(); ++i) {
3505 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3506 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3507 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3508 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3509 }
3510
3511 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003512 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003513 auto find_codec =
3514 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3515 for (size_t i = 0; i != codecs.size(); ++i) {
3516 const cricket::AudioCodec& codec = codecs[i];
3517 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3518 codec.clockrate == format.clockrate_hz &&
3519 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003520 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003521 }
3522 }
3523 return -1;
3524 };
3525
3526 // Ensure all supplementary codecs are generated last. Their internal ordering
3527 // is not important.
3528 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3529 const int num_specs = static_cast<int>(specs.size());
3530 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3531 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3532 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3533 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3534 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3535 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3536 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3537}