blob: 4e807889190a0f4ab8d4025ca2832f446a6017ca [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;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200625 stats.concealment_events = 12;
solenberg85a04962015-10-27 03:35:21 -0700626 stats.expand_rate = 5.67f;
627 stats.speech_expand_rate = 8.90f;
628 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200629 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700630 stats.accelerate_rate = 4.56f;
631 stats.preemptive_expand_rate = 7.89f;
632 stats.decoding_calls_to_silence_generator = 12;
633 stats.decoding_calls_to_neteq = 345;
634 stats.decoding_normal = 67890;
635 stats.decoding_plc = 1234;
636 stats.decoding_cng = 5678;
637 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700638 stats.decoding_muted_output = 3456;
639 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200640 return stats;
641 }
642 void SetAudioReceiveStreamStats() {
643 for (auto* s : call_.GetAudioReceiveStreams()) {
644 s->SetStats(GetAudioReceiveStreamStats());
645 }
646 }
647 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700648 const auto stats = GetAudioReceiveStreamStats();
649 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
650 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
651 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
652 EXPECT_EQ(info.packets_lost, stats.packets_lost);
653 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
654 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800655 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700656 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
657 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
658 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200659 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700660 stats.jitter_buffer_preferred_ms);
661 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
662 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700663 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
664 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200665 EXPECT_EQ(info.concealment_events, stats.concealment_events);
solenberg85a04962015-10-27 03:35:21 -0700666 EXPECT_EQ(info.expand_rate, stats.expand_rate);
667 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
668 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200669 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700670 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
671 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200672 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700673 stats.decoding_calls_to_silence_generator);
674 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
675 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
676 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
677 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
678 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700679 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700680 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200681 }
hbos1acfbd22016-11-17 23:43:29 -0800682 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
683 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
684 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
685 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
686 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
687 codec.ToCodecParameters());
688 }
689 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
690 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
691 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
692 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
693 codec.ToCodecParameters());
694 }
695 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200696
peah8271d042016-11-22 07:24:52 -0800697 bool IsHighPassFilterEnabled() {
698 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
699 }
700
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700702 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700703 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800704 webrtc::test::MockGainControl& apm_gc_;
705 webrtc::test::MockEchoCancellation& apm_ec_;
706 webrtc::test::MockNoiseSuppression& apm_ns_;
707 webrtc::test::MockVoiceDetection& apm_vd_;
708 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700709 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200710 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700712 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700713 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200714 cricket::AudioSendParameters send_parameters_;
715 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800716 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700717 webrtc::AudioProcessing::Config apm_config_;
718
stefanba4c0e42016-02-04 04:12:24 -0800719 private:
720 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721};
722
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723// Tests that we can create and destroy a channel.
724TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700725 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726}
727
solenberg31fec402016-05-06 02:13:12 -0700728// Test that we can add a send stream and that it has the correct defaults.
729TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
730 EXPECT_TRUE(SetupChannel());
731 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800732 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
733 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
734 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700735 EXPECT_EQ("", config.rtp.c_name);
736 EXPECT_EQ(0u, config.rtp.extensions.size());
737 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
738 config.send_transport);
739}
740
741// Test that we can add a receive stream and that it has the correct defaults.
742TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
743 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800744 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700745 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800746 GetRecvStreamConfig(kSsrcX);
747 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700748 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
749 EXPECT_FALSE(config.rtp.transport_cc);
750 EXPECT_EQ(0u, config.rtp.extensions.size());
751 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
752 config.rtcp_send_transport);
753 EXPECT_EQ("", config.sync_group);
754}
755
stefanba4c0e42016-02-04 04:12:24 -0800756TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700757 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800758 bool opus_found = false;
759 for (cricket::AudioCodec codec : codecs) {
760 if (codec.name == "opus") {
761 EXPECT_TRUE(HasTransportCc(codec));
762 opus_found = true;
763 }
764 }
765 EXPECT_TRUE(opus_found);
766}
767
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768// Test that we set our inbound codecs properly, including changing PT.
769TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700770 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200771 cricket::AudioRecvParameters parameters;
772 parameters.codecs.push_back(kIsacCodec);
773 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800774 parameters.codecs.push_back(kTelephoneEventCodec1);
775 parameters.codecs.push_back(kTelephoneEventCodec2);
776 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 parameters.codecs[2].id = 126;
778 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800779 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700780 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
781 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
782 {{0, {"PCMU", 8000, 1}},
783 {106, {"ISAC", 16000, 1}},
784 {126, {"telephone-event", 8000, 1}},
785 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
788// Test that we fail to set an unknown inbound codec.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700793 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
797// Test that we fail if we have duplicate types in the inbound list.
798TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700799 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200800 cricket::AudioRecvParameters parameters;
801 parameters.codecs.push_back(kIsacCodec);
802 parameters.codecs.push_back(kCn16000Codec);
803 parameters.codecs[1].id = kIsacCodec.id;
804 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805}
806
807// Test that we can decode OPUS without stereo parameters.
808TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700809 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 cricket::AudioRecvParameters parameters;
811 parameters.codecs.push_back(kIsacCodec);
812 parameters.codecs.push_back(kPcmuCodec);
813 parameters.codecs.push_back(kOpusCodec);
814 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800815 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700816 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
817 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
818 {{0, {"PCMU", 8000, 1}},
819 {103, {"ISAC", 16000, 1}},
820 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821}
822
823// Test that we can decode OPUS with stereo = 0.
824TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700825 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 cricket::AudioRecvParameters parameters;
827 parameters.codecs.push_back(kIsacCodec);
828 parameters.codecs.push_back(kPcmuCodec);
829 parameters.codecs.push_back(kOpusCodec);
830 parameters.codecs[2].params["stereo"] = "0";
831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800832 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700833 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
834 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
835 {{0, {"PCMU", 8000, 1}},
836 {103, {"ISAC", 16000, 1}},
837 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
840// Test that we can decode OPUS with stereo = 1.
841TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700842 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200843 cricket::AudioRecvParameters parameters;
844 parameters.codecs.push_back(kIsacCodec);
845 parameters.codecs.push_back(kPcmuCodec);
846 parameters.codecs.push_back(kOpusCodec);
847 parameters.codecs[2].params["stereo"] = "1";
848 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800849 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700850 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
851 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
852 {{0, {"PCMU", 8000, 1}},
853 {103, {"ISAC", 16000, 1}},
854 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855}
856
857// Test that changes to recv codecs are applied to all streams.
858TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700859 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200860 cricket::AudioRecvParameters parameters;
861 parameters.codecs.push_back(kIsacCodec);
862 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800863 parameters.codecs.push_back(kTelephoneEventCodec1);
864 parameters.codecs.push_back(kTelephoneEventCodec2);
865 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200866 parameters.codecs[2].id = 126;
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700868 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
869 EXPECT_TRUE(AddRecvStream(ssrc));
870 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
871 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
872 {{0, {"PCMU", 8000, 1}},
873 {106, {"ISAC", 16000, 1}},
874 {126, {"telephone-event", 8000, 1}},
875 {107, {"telephone-event", 32000, 1}}})));
876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877}
878
879TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700880 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 cricket::AudioRecvParameters parameters;
882 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885
solenberg2100c0b2017-03-01 11:29:29 -0800886 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800887 ASSERT_EQ(1, dm.count(106));
888 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889}
890
891// Test that we can apply the same set of codecs again while playing.
892TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700893 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 cricket::AudioRecvParameters parameters;
895 parameters.codecs.push_back(kIsacCodec);
896 parameters.codecs.push_back(kCn16000Codec);
897 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700898 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
deadbeefcb383672017-04-26 16:28:42 -0700901 // Remapping a payload type to a different codec should fail.
902 parameters.codecs[0] = kOpusCodec;
903 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800905 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906}
907
908// Test that we can add a codec while playing.
909TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700910 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 cricket::AudioRecvParameters parameters;
912 parameters.codecs.push_back(kIsacCodec);
913 parameters.codecs.push_back(kCn16000Codec);
914 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700915 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 parameters.codecs.push_back(kOpusCodec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800919 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
deadbeefcb383672017-04-26 16:28:42 -0700922// Test that we accept adding the same codec with a different payload type.
923// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
924TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
925 EXPECT_TRUE(SetupRecvStream());
926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
929
930 ++parameters.codecs[0].id;
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932}
933
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000937 // Test that when autobw is enabled, bitrate is kept as the default
938 // value. autobw is enabled for the following tests because the target
939 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
941 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700942 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
ossu20a4b3f2017-04-27 02:08:52 -0700947 // opus, default bitrate == 32000 in mono.
948 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700955 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
956 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700957 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
961 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
962 // Rates above the max (510000) should be capped.
963 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700967 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000968
969 // Test that we can only set a maximum bitrate for a fixed-rate codec
970 // if it's bigger than the fixed rate.
971
972 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700973 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980}
981
982TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700983 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200984 const int kDesiredBitrate = 128000;
985 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700986 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700988 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000989
990 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800991 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
solenberg2100c0b2017-03-01 11:29:29 -0800993 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000994}
995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996// Test that bitrate cannot be set for CBR codecs.
997// Bitrate is ignored if it is higher than the fixed bitrate.
998// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001000 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001003 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001004 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001005
1006 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009
1010 send_parameters_.max_bandwidth_bps = 128;
1011 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013}
1014
skvlade0d46372016-04-07 22:59:22 -07001015// Test that the per-stream bitrate limit and the global
1016// bitrate limit both apply.
1017TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1018 EXPECT_TRUE(SetupSendStream());
1019
ossu20a4b3f2017-04-27 02:08:52 -07001020 // opus, default bitrate == 32000.
1021 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001022 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1023 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1024 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1025
1026 // CBR codecs allow both maximums to exceed the bitrate.
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1029 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1030 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1031
1032 // CBR codecs don't allow per stream maximums to be too low.
1033 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1035}
1036
1037// Test that an attempt to set RtpParameters for a stream that does not exist
1038// fails.
1039TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1040 EXPECT_TRUE(SetupChannel());
1041 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001042 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001043 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1044
1045 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001047}
1048
1049TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001050 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001051 // This test verifies that setting RtpParameters succeeds only if
1052 // the structure contains exactly one encoding.
1053 // TODO(skvlad): Update this test when we start supporting setting parameters
1054 // for each encoding individually.
1055
1056 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001057 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001058 // Two or more encodings should result in failure.
1059 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001060 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001061 // Zero encodings should also fail.
1062 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001064}
1065
1066// Changing the SSRC through RtpParameters is not allowed.
1067TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1068 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001069 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001070 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001072}
1073
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001076TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001079 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082 ASSERT_EQ(1u, parameters.encodings.size());
1083 ASSERT_TRUE(parameters.encodings[0].active);
1084 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087
1088 // Now change it back to active and verify we resume sending.
1089 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1091 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092}
1093
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001094// Test that SetRtpSendParameters configures the correct encoding channel for
1095// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001096TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1097 SetupForMultiSendStream();
1098 // Create send streams.
1099 for (uint32_t ssrc : kSsrcs4) {
1100 EXPECT_TRUE(
1101 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1102 }
1103 // Configure one stream to be limited by the stream config, another to be
1104 // limited by the global max, and the third one with no per-stream limit
1105 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001106 SetGlobalMaxBitrate(kOpusCodec, 32000);
1107 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1108 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001109 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1110
ossu20a4b3f2017-04-27 02:08:52 -07001111 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1112 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1113 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001114
1115 // Remove the global cap; the streams should switch to their respective
1116 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001117 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001118 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1119 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1120 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001121}
1122
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001123// Test that GetRtpSendParameters returns the currently configured codecs.
1124TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001125 EXPECT_TRUE(SetupSendStream());
1126 cricket::AudioSendParameters parameters;
1127 parameters.codecs.push_back(kIsacCodec);
1128 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001129 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001130
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1134 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135}
1136
deadbeefcb443432016-12-12 11:12:36 -08001137// Test that GetRtpSendParameters returns an SSRC.
1138TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1139 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001140 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001141 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001142 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001143}
1144
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001145// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001146TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147 EXPECT_TRUE(SetupSendStream());
1148 cricket::AudioSendParameters parameters;
1149 parameters.codecs.push_back(kIsacCodec);
1150 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001151 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152
solenberg2100c0b2017-03-01 11:29:29 -08001153 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
1155 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001156 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001159 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1160 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001161}
1162
minyuececec102017-03-27 13:04:25 -07001163// Test that max_bitrate_bps in send stream config gets updated correctly when
1164// SetRtpSendParameters is called.
1165TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1166 webrtc::test::ScopedFieldTrials override_field_trials(
1167 "WebRTC-Audio-SendSideBwe/Enabled/");
1168 EXPECT_TRUE(SetupSendStream());
1169 cricket::AudioSendParameters send_parameters;
1170 send_parameters.codecs.push_back(kOpusCodec);
1171 SetSendParameters(send_parameters);
1172
1173 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1174 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1175 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1176
1177 constexpr int kMaxBitrateBps = 6000;
1178 rtp_parameters.encodings[0].max_bitrate_bps =
1179 rtc::Optional<int>(kMaxBitrateBps);
1180 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1181
1182 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1183 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1184}
1185
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001186// Test that GetRtpReceiveParameters returns the currently configured codecs.
1187TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1188 EXPECT_TRUE(SetupRecvStream());
1189 cricket::AudioRecvParameters parameters;
1190 parameters.codecs.push_back(kIsacCodec);
1191 parameters.codecs.push_back(kPcmuCodec);
1192 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1193
1194 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001195 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001196 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1197 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1198 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1199}
1200
deadbeefcb443432016-12-12 11:12:36 -08001201// Test that GetRtpReceiveParameters returns an SSRC.
1202TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1203 EXPECT_TRUE(SetupRecvStream());
1204 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001205 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001206 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001207 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001208}
1209
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210// Test that if we set/get parameters multiple times, we get the same results.
1211TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1212 EXPECT_TRUE(SetupRecvStream());
1213 cricket::AudioRecvParameters parameters;
1214 parameters.codecs.push_back(kIsacCodec);
1215 parameters.codecs.push_back(kPcmuCodec);
1216 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1217
1218 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001219 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001220
1221 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001222 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223
1224 // ... And this shouldn't change the params returned by
1225 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001226 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1227 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001228}
1229
deadbeef3bc15102017-04-20 19:25:07 -07001230// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1231// aren't signaled. It should return an empty "RtpEncodingParameters" when
1232// configured to receive an unsignaled stream and no packets have been received
1233// yet, and start returning the SSRC once a packet has been received.
1234TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1235 ASSERT_TRUE(SetupChannel());
1236 // Call necessary methods to configure receiving a default stream as
1237 // soon as it arrives.
1238 cricket::AudioRecvParameters parameters;
1239 parameters.codecs.push_back(kIsacCodec);
1240 parameters.codecs.push_back(kPcmuCodec);
1241 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1242
1243 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1244 // stream. Should return nothing.
1245 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1246
1247 // Set a sink for an unsignaled stream.
1248 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1249 // Value of "0" means "unsignaled stream".
1250 channel_->SetRawAudioSink(0, std::move(fake_sink));
1251
1252 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1253 // in this method means "unsignaled stream".
1254 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1255 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1256 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1257
1258 // Receive PCMU packet (SSRC=1).
1259 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1260
1261 // The |ssrc| member should still be unset.
1262 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1263 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1264 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1265}
1266
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001267// Test that we apply codecs properly.
1268TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001269 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001270 cricket::AudioSendParameters parameters;
1271 parameters.codecs.push_back(kIsacCodec);
1272 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001273 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001274 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001275 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001276 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001277 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1278 EXPECT_EQ(96, send_codec_spec.payload_type);
1279 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1280 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1281 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1282 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001283 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
ossu20a4b3f2017-04-27 02:08:52 -07001286// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1287// AudioSendStream.
1288TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001289 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001290 cricket::AudioSendParameters parameters;
1291 parameters.codecs.push_back(kIsacCodec);
1292 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001293 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 parameters.codecs[0].id = 96;
1295 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001296 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001297 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001298 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001299 // Calling SetSendCodec again with same codec which is already set.
1300 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001301 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001302 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001303}
1304
ossu20a4b3f2017-04-27 02:08:52 -07001305// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1306// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001307
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001308// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001309TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001310 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 cricket::AudioSendParameters parameters;
1312 parameters.codecs.push_back(kOpusCodec);
1313 parameters.codecs[0].bitrate = 0;
1314 parameters.codecs[0].clockrate = 50000;
1315 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316}
1317
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001318// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001320 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001321 cricket::AudioSendParameters parameters;
1322 parameters.codecs.push_back(kOpusCodec);
1323 parameters.codecs[0].bitrate = 0;
1324 parameters.codecs[0].channels = 0;
1325 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326}
1327
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001328// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001330 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001331 cricket::AudioSendParameters parameters;
1332 parameters.codecs.push_back(kOpusCodec);
1333 parameters.codecs[0].bitrate = 0;
1334 parameters.codecs[0].channels = 0;
1335 parameters.codecs[0].params["stereo"] = "1";
1336 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337}
1338
1339// Test that if channel is 1 for opus and there's no stereo, we fail.
1340TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001341 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 cricket::AudioSendParameters parameters;
1343 parameters.codecs.push_back(kOpusCodec);
1344 parameters.codecs[0].bitrate = 0;
1345 parameters.codecs[0].channels = 1;
1346 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347}
1348
1349// Test that if channel is 1 for opus and stereo=0, we fail.
1350TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001351 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001352 cricket::AudioSendParameters parameters;
1353 parameters.codecs.push_back(kOpusCodec);
1354 parameters.codecs[0].bitrate = 0;
1355 parameters.codecs[0].channels = 1;
1356 parameters.codecs[0].params["stereo"] = "0";
1357 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358}
1359
1360// Test that if channel is 1 for opus and stereo=1, we fail.
1361TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001362 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 cricket::AudioSendParameters parameters;
1364 parameters.codecs.push_back(kOpusCodec);
1365 parameters.codecs[0].bitrate = 0;
1366 parameters.codecs[0].channels = 1;
1367 parameters.codecs[0].params["stereo"] = "1";
1368 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001369}
1370
ossu20a4b3f2017-04-27 02:08:52 -07001371// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001378 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001379}
1380
ossu20a4b3f2017-04-27 02:08:52 -07001381// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001383 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 cricket::AudioSendParameters parameters;
1385 parameters.codecs.push_back(kOpusCodec);
1386 parameters.codecs[0].bitrate = 0;
1387 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001388 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001389 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001390}
1391
ossu20a4b3f2017-04-27 02:08:52 -07001392// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001393TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001394 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001395 cricket::AudioSendParameters parameters;
1396 parameters.codecs.push_back(kOpusCodec);
1397 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001398 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001400 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001401 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001402
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001404 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001405 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001406}
1407
ossu20a4b3f2017-04-27 02:08:52 -07001408// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001410 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 cricket::AudioSendParameters parameters;
1412 parameters.codecs.push_back(kOpusCodec);
1413 parameters.codecs[0].bitrate = 0;
1414 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001415 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001416 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001417}
1418
ossu20a4b3f2017-04-27 02:08:52 -07001419// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001420TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001421 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001422 cricket::AudioSendParameters parameters;
1423 parameters.codecs.push_back(kOpusCodec);
1424 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001425 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001426 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001427 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001428 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001429
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001433}
1434
ossu20a4b3f2017-04-27 02:08:52 -07001435// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001437 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 cricket::AudioSendParameters parameters;
1439 parameters.codecs.push_back(kOpusCodec);
1440 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001441 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001442 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1443 EXPECT_EQ(111, spec.payload_type);
1444 EXPECT_EQ(96000, spec.target_bitrate_bps);
1445 EXPECT_EQ("opus", spec.format.name);
1446 EXPECT_EQ(2, spec.format.num_channels);
1447 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448}
1449
ossu20a4b3f2017-04-27 02:08:52 -07001450// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001452 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001453 cricket::AudioSendParameters parameters;
1454 parameters.codecs.push_back(kOpusCodec);
1455 parameters.codecs[0].bitrate = 30000;
1456 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001457 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001458 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459}
1460
ossu20a4b3f2017-04-27 02:08:52 -07001461// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001463 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001464 cricket::AudioSendParameters parameters;
1465 parameters.codecs.push_back(kOpusCodec);
1466 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001467 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001468 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469}
1470
ossu20a4b3f2017-04-27 02:08:52 -07001471// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001473 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001474 cricket::AudioSendParameters parameters;
1475 parameters.codecs.push_back(kOpusCodec);
1476 parameters.codecs[0].bitrate = 30000;
1477 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001478 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001479 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001480}
1481
stefan13f1a0a2016-11-30 07:22:58 -08001482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1483 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1484 200000);
1485}
1486
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1488 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1489}
1490
1491TEST_F(WebRtcVoiceEngineTestFake,
1492 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1493 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1494}
1495
1496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1497 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1498}
1499
1500TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001501 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001502 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1503 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001504 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001505 SetSendParameters(send_parameters_);
1506 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1507 << "Setting max bitrate should keep previous min bitrate.";
1508 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1509 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001510 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001511}
1512
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001513// Test that we can enable NACK with opus as caller.
1514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001515 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001516 cricket::AudioSendParameters parameters;
1517 parameters.codecs.push_back(kOpusCodec);
1518 parameters.codecs[0].AddFeedbackParam(
1519 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1520 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001523 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001526// Test that we can enable NACK with opus as callee.
1527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].AddFeedbackParam(
1532 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1533 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001534 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001535 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001536 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001538
1539 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001540 cricket::StreamParams::CreateLegacy(kSsrcX)));
1541 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001542}
1543
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001544// Test that we can enable NACK on receive streams.
1545TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001546 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001547 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 cricket::AudioSendParameters parameters;
1549 parameters.codecs.push_back(kOpusCodec);
1550 parameters.codecs[0].AddFeedbackParam(
1551 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1552 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001553 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1554 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001555 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1557 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001558}
1559
1560// Test that we can disable NACK.
1561TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001562 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001563 cricket::AudioSendParameters parameters;
1564 parameters.codecs.push_back(kOpusCodec);
1565 parameters.codecs[0].AddFeedbackParam(
1566 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1567 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001568 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001569 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 parameters.codecs.clear();
1572 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575}
1576
1577// Test that we can disable NACK on receive streams.
1578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001580 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001581 cricket::AudioSendParameters parameters;
1582 parameters.codecs.push_back(kOpusCodec);
1583 parameters.codecs[0].AddFeedbackParam(
1584 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1585 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001587 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1588 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001590 parameters.codecs.clear();
1591 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001593 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1594 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595}
1596
1597// Test that NACK is enabled on a new receive stream.
1598TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kIsacCodec);
1602 parameters.codecs.push_back(kCn16000Codec);
1603 parameters.codecs[0].AddFeedbackParam(
1604 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1605 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001606 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001607 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_TRUE(AddRecvStream(kSsrcY));
1610 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1611 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1612 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613}
1614
stefanba4c0e42016-02-04 04:12:24 -08001615TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001617 cricket::AudioSendParameters send_parameters;
1618 send_parameters.codecs.push_back(kOpusCodec);
1619 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001620 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001621
1622 cricket::AudioRecvParameters recv_parameters;
1623 recv_parameters.codecs.push_back(kIsacCodec);
1624 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001625 EXPECT_TRUE(AddRecvStream(kSsrcX));
1626 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001627 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001628 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001629
ossudedfd282016-06-14 07:12:39 -07001630 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001631 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001632 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001633 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001634 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001635}
1636
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001637// Test that we can switch back and forth between Opus and ISAC with CN.
1638TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001639 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001640
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001641 cricket::AudioSendParameters opus_parameters;
1642 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001643 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001644 {
ossu20a4b3f2017-04-27 02:08:52 -07001645 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1646 EXPECT_EQ(111, spec.payload_type);
1647 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001648 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001649
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001650 cricket::AudioSendParameters isac_parameters;
1651 isac_parameters.codecs.push_back(kIsacCodec);
1652 isac_parameters.codecs.push_back(kCn16000Codec);
1653 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001655 {
ossu20a4b3f2017-04-27 02:08:52 -07001656 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1657 EXPECT_EQ(103, spec.payload_type);
1658 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001659 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001660
solenberg059fb442016-10-26 05:12:24 -07001661 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001662 {
ossu20a4b3f2017-04-27 02:08:52 -07001663 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1664 EXPECT_EQ(111, spec.payload_type);
1665 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001666 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667}
1668
1669// Test that we handle various ways of specifying bitrate.
1670TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 cricket::AudioSendParameters parameters;
1673 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001674 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001675 {
ossu20a4b3f2017-04-27 02:08:52 -07001676 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1677 EXPECT_EQ(103, spec.payload_type);
1678 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1679 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001680 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001682 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001684 {
ossu20a4b3f2017-04-27 02:08:52 -07001685 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1686 EXPECT_EQ(103, spec.payload_type);
1687 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1688 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001689 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001690 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(103, spec.payload_type);
1695 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1696 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001697 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001700 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001701 {
ossu20a4b3f2017-04-27 02:08:52 -07001702 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1703 EXPECT_EQ(0, spec.payload_type);
1704 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1705 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001706 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001707
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001710 {
ossu20a4b3f2017-04-27 02:08:52 -07001711 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1712 EXPECT_EQ(0, spec.payload_type);
1713 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1714 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001715 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 parameters.codecs[0] = kOpusCodec;
1718 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001720 {
ossu20a4b3f2017-04-27 02:08:52 -07001721 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1722 EXPECT_EQ(111, spec.payload_type);
1723 EXPECT_STREQ("opus", spec.format.name.c_str());
1724 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001725 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001726}
1727
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001728// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001730 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 cricket::AudioSendParameters parameters;
1732 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001733}
1734
1735// Test that we can set send codecs even with telephone-event codec as the first
1736// one on the list.
1737TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001738 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001740 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001741 parameters.codecs.push_back(kIsacCodec);
1742 parameters.codecs.push_back(kPcmuCodec);
1743 parameters.codecs[0].id = 98; // DTMF
1744 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001746 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1747 EXPECT_EQ(96, spec.payload_type);
1748 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001749 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001750}
1751
solenberg31642aa2016-03-14 08:00:37 -07001752// Test that payload type range is limited for telephone-event codec.
1753TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001754 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001755 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001756 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001757 parameters.codecs.push_back(kIsacCodec);
1758 parameters.codecs[0].id = 0; // DTMF
1759 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001761 EXPECT_TRUE(channel_->CanInsertDtmf());
1762 parameters.codecs[0].id = 128; // DTMF
1763 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1764 EXPECT_FALSE(channel_->CanInsertDtmf());
1765 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001766 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001767 EXPECT_TRUE(channel_->CanInsertDtmf());
1768 parameters.codecs[0].id = -1; // DTMF
1769 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1770 EXPECT_FALSE(channel_->CanInsertDtmf());
1771}
1772
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001773// Test that we can set send codecs even with CN codec as the first
1774// one on the list.
1775TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001776 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001777 cricket::AudioSendParameters parameters;
1778 parameters.codecs.push_back(kCn16000Codec);
1779 parameters.codecs.push_back(kIsacCodec);
1780 parameters.codecs.push_back(kPcmuCodec);
1781 parameters.codecs[0].id = 98; // wideband CN
1782 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001783 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001784 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1785 EXPECT_EQ(96, send_codec_spec.payload_type);
1786 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001787 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001788}
1789
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001790// Test that we set VAD and DTMF types correctly as caller.
1791TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001792 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001793 cricket::AudioSendParameters parameters;
1794 parameters.codecs.push_back(kIsacCodec);
1795 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 parameters.codecs.push_back(kCn16000Codec);
1798 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001799 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 parameters.codecs[0].id = 96;
1801 parameters.codecs[2].id = 97; // wideband CN
1802 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001804 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1805 EXPECT_EQ(96, send_codec_spec.payload_type);
1806 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1807 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001808 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001809 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810}
1811
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001812// Test that we set VAD and DTMF types correctly as callee.
1813TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001814 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 cricket::AudioSendParameters parameters;
1816 parameters.codecs.push_back(kIsacCodec);
1817 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001818 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001819 parameters.codecs.push_back(kCn16000Codec);
1820 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001821 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 parameters.codecs[0].id = 96;
1823 parameters.codecs[2].id = 97; // wideband CN
1824 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001826 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001827 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001828
ossu20a4b3f2017-04-27 02:08:52 -07001829 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1830 EXPECT_EQ(96, send_codec_spec.payload_type);
1831 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1832 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001833 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001834 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001835}
1836
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001837// Test that we only apply VAD if we have a CN codec that matches the
1838// send codec clockrate.
1839TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001840 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 parameters.codecs.push_back(kIsacCodec);
1844 parameters.codecs.push_back(kCn16000Codec);
1845 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001846 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001847 {
ossu20a4b3f2017-04-27 02:08:52 -07001848 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1849 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1850 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001851 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001852 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001853 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001854 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001855 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001856 {
ossu20a4b3f2017-04-27 02:08:52 -07001857 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1858 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1859 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001860 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001861 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001862 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001864 {
ossu20a4b3f2017-04-27 02:08:52 -07001865 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1866 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1867 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001868 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001869 }
Brave Yao5225dd82015-03-26 07:39:19 +08001870 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001873 {
ossu20a4b3f2017-04-27 02:08:52 -07001874 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1875 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1876 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001877 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878}
1879
1880// Test that we perform case-insensitive matching of codec names.
1881TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001882 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001883 cricket::AudioSendParameters parameters;
1884 parameters.codecs.push_back(kIsacCodec);
1885 parameters.codecs.push_back(kPcmuCodec);
1886 parameters.codecs.push_back(kCn16000Codec);
1887 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001888 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 parameters.codecs[0].name = "iSaC";
1890 parameters.codecs[0].id = 96;
1891 parameters.codecs[2].id = 97; // wideband CN
1892 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001894 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1895 EXPECT_EQ(96, send_codec_spec.payload_type);
1896 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1897 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001898 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001899 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900}
1901
stefanba4c0e42016-02-04 04:12:24 -08001902class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1903 public:
1904 WebRtcVoiceEngineWithSendSideBweTest()
1905 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1906};
1907
1908TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1909 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001910 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001911 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001912 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1913 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1914 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001915 extension.id);
1916 return;
1917 }
1918 }
1919 FAIL() << "Transport sequence number extension not in header-extension list.";
1920}
1921
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001922// Test support for audio level header extension.
1923TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001924 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001925}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001926TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001927 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001928}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001929
solenbergd4adce42016-11-17 06:26:52 -08001930// Test support for transport sequence number header extension.
1931TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1932 TestSetSendRtpHeaderExtensions(
1933 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001934}
solenbergd4adce42016-11-17 06:26:52 -08001935TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1936 TestSetRecvRtpHeaderExtensions(
1937 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001938}
1939
solenberg1ac56142015-10-13 03:58:19 -07001940// Test that we can create a channel and start sending on it.
1941TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001942 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001943 SetSendParameters(send_parameters_);
1944 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001945 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001946 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001947 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001948}
1949
1950// Test that a channel will send if and only if it has a source and is enabled
1951// for sending.
1952TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001953 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001954 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001955 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001956 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001957 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1958 SetAudioSend(kSsrcX, true, &fake_source_);
1959 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1960 SetAudioSend(kSsrcX, true, nullptr);
1961 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001962}
1963
solenberg94218532016-06-16 10:53:22 -07001964// Test that a channel is muted/unmuted.
1965TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1966 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001967 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001968 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1969 SetAudioSend(kSsrcX, true, nullptr);
1970 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1971 SetAudioSend(kSsrcX, false, nullptr);
1972 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001973}
1974
solenberg6d6e7c52016-04-13 09:07:30 -07001975// Test that SetSendParameters() does not alter a stream's send state.
1976TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1977 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001978 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001979
1980 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001981 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001983
1984 // Changing RTP header extensions will recreate the AudioSendStream.
1985 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001986 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001987 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001988 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001989
1990 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001991 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001992 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001993
1994 // Changing RTP header extensions will recreate the AudioSendStream.
1995 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001996 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001998}
1999
solenberg1ac56142015-10-13 03:58:19 -07002000// Test that we can create a channel and start playing out on it.
2001TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002002 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002003 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002004 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002006 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002007 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002008}
2009
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002010// Test that we can add and remove send streams.
2011TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2012 SetupForMultiSendStream();
2013
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002015 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002016
solenbergc96df772015-10-21 13:01:53 -07002017 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002018 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002019 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002020 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002022 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023 }
tfarina5237aaf2015-11-10 23:44:30 -08002024 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002025
solenbergc96df772015-10-21 13:01:53 -07002026 // Delete the send streams.
2027 for (uint32_t ssrc : kSsrcs4) {
2028 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002029 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002030 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031 }
solenbergc96df772015-10-21 13:01:53 -07002032 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002033}
2034
2035// Test SetSendCodecs correctly configure the codecs in all send streams.
2036TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2037 SetupForMultiSendStream();
2038
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002040 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002042 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 }
2044
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002045 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002047 parameters.codecs.push_back(kIsacCodec);
2048 parameters.codecs.push_back(kCn16000Codec);
2049 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002050 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051
2052 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002053 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002054 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2055 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002056 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2057 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2058 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002059 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 }
2061
minyue7a973442016-10-20 03:27:12 -07002062 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002063 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002064 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002065 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002066 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2067 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002068 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2069 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2070 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071 }
2072}
2073
2074// Test we can SetSend on all send streams correctly.
2075TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2076 SetupForMultiSendStream();
2077
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002078 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002079 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002081 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002082 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002083 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002084 }
2085
2086 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002087 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002088 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002090 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002091 }
2092
2093 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002094 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002095 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002097 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002098 }
2099}
2100
2101// Test we can set the correct statistics on all send streams.
2102TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2103 SetupForMultiSendStream();
2104
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002106 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002108 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 }
solenberg85a04962015-10-27 03:35:21 -07002110
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002111 // Create a receive stream to check that none of the send streams end up in
2112 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002113 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002114
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002116 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002117 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002118 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002119
solenberg85a04962015-10-27 03:35:21 -07002120 // Check stats for the added streams.
2121 {
2122 cricket::VoiceMediaInfo info;
2123 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124
solenberg85a04962015-10-27 03:35:21 -07002125 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002126 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002127 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002128 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002129 }
hbos1acfbd22016-11-17 23:43:29 -08002130 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002131
2132 // We have added one receive stream. We should see empty stats.
2133 EXPECT_EQ(info.receivers.size(), 1u);
2134 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 }
solenberg1ac56142015-10-13 03:58:19 -07002136
solenberg2100c0b2017-03-01 11:29:29 -08002137 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002138 {
2139 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002140 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002141 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002142 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002143 EXPECT_EQ(0u, info.receivers.size());
2144 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002145
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002146 // Deliver a new packet - a default receive stream should be created and we
2147 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002148 {
2149 cricket::VoiceMediaInfo info;
2150 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2151 SetAudioReceiveStreamStats();
2152 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002153 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002154 EXPECT_EQ(1u, info.receivers.size());
2155 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002156 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002157 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158}
2159
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002160// Test that we can add and remove receive streams, and do proper send/playout.
2161// We can receive on multiple streams while sending one stream.
2162TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002163 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002164
solenberg1ac56142015-10-13 03:58:19 -07002165 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002166 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002167 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168
solenberg1ac56142015-10-13 03:58:19 -07002169 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002170 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002171 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002172 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002173
solenberg1ac56142015-10-13 03:58:19 -07002174 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002175 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002176
2177 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002178 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2179 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2180 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181
2182 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002183 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002184 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
2186 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002187 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002188 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2189 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002190
aleloi84ef6152016-08-04 05:28:21 -07002191 // Restart playout and make sure recv streams are played out.
2192 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002193 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2194 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002195
aleloi84ef6152016-08-04 05:28:21 -07002196 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002197 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2198 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002199}
2200
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002201// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002202// and start sending on it.
2203TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002204 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002205 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2206 EXPECT_CALL(apm_gc_,
2207 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002208 SetSendParameters(send_parameters_);
2209 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002210 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002211 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002212 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002213}
2214
wu@webrtc.org97077a32013-10-25 21:18:33 +00002215TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002216 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002217 EXPECT_CALL(adm_,
2218 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002219 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2220 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002221 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2222 send_parameters_.options.tx_agc_digital_compression_gain =
2223 rtc::Optional<uint16_t>(9);
2224 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2225 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002226 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2227 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2228 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002229 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002230
2231 // Check interaction with adjust_agc_delta. Both should be respected, for
2232 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002233 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002234 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002236}
2237
wu@webrtc.org97077a32013-10-25 21:18:33 +00002238TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002239 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002240 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2241 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002242 send_parameters_.options.recording_sample_rate =
2243 rtc::Optional<uint32_t>(48000);
2244 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002245 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002246}
2247
minyue6b825df2016-10-31 04:08:32 -07002248TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2249 EXPECT_TRUE(SetupSendStream());
2250 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2251 send_parameters_.options.audio_network_adaptor_config =
2252 rtc::Optional<std::string>("1234");
2253 SetSendParameters(send_parameters_);
2254 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002255 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002256}
2257
2258TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2259 EXPECT_TRUE(SetupSendStream());
2260 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2261 send_parameters_.options.audio_network_adaptor_config =
2262 rtc::Optional<std::string>("1234");
2263 SetSendParameters(send_parameters_);
2264 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002265 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002266 cricket::AudioOptions options;
2267 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002268 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002269 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002270}
2271
2272TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2273 EXPECT_TRUE(SetupSendStream());
2274 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2275 send_parameters_.options.audio_network_adaptor_config =
2276 rtc::Optional<std::string>("1234");
2277 SetSendParameters(send_parameters_);
2278 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002279 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002280 const int initial_num = call_.GetNumCreatedSendStreams();
2281 cricket::AudioOptions options;
2282 options.audio_network_adaptor = rtc::Optional<bool>();
2283 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2284 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002285 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002286 // AudioSendStream not expected to be recreated.
2287 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2288 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002289 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002290}
2291
michaelt6672b262017-01-11 10:17:59 -08002292class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2293 : public WebRtcVoiceEngineTestFake {
2294 public:
2295 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2296 : WebRtcVoiceEngineTestFake(
2297 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2298 "Enabled/") {}
2299};
2300
2301TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2302 EXPECT_TRUE(SetupSendStream());
2303 cricket::AudioSendParameters parameters;
2304 parameters.codecs.push_back(kOpusCodec);
2305 SetSendParameters(parameters);
2306 const int initial_num = call_.GetNumCreatedSendStreams();
2307 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2308
2309 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2310 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002311 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2312 constexpr int kMinOverheadBps =
2313 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002314
2315 constexpr int kOpusMinBitrateBps = 6000;
2316 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002317 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002318 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002319 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002320 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002321
2322 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2323 parameters.options.audio_network_adaptor_config =
2324 rtc::Optional<std::string>("1234");
2325 SetSendParameters(parameters);
2326
ossu11bfc532017-02-16 05:37:06 -08002327 constexpr int kMinOverheadWithAnaBps =
2328 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002329
2330 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002331 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002332
minyuececec102017-03-27 13:04:25 -07002333 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002335}
2336
minyuececec102017-03-27 13:04:25 -07002337// This test is similar to
2338// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2339// additional field trial.
2340TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2341 SetRtpSendParameterUpdatesMaxBitrate) {
2342 EXPECT_TRUE(SetupSendStream());
2343 cricket::AudioSendParameters send_parameters;
2344 send_parameters.codecs.push_back(kOpusCodec);
2345 SetSendParameters(send_parameters);
2346
2347 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2348 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2349 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2350
2351 constexpr int kMaxBitrateBps = 6000;
2352 rtp_parameters.encodings[0].max_bitrate_bps =
2353 rtc::Optional<int>(kMaxBitrateBps);
2354 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2355
2356 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2357#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2358 constexpr int kMinOverhead = 3333;
2359#else
2360 constexpr int kMinOverhead = 6666;
2361#endif
2362 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2363}
2364
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002366// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002368 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002369 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002370}
2371
2372TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2373 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002374 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002375 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002376 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002377 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002378 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002379 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002380 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381
solenberg85a04962015-10-27 03:35:21 -07002382 // Check stats for the added streams.
2383 {
2384 cricket::VoiceMediaInfo info;
2385 EXPECT_EQ(true, channel_->GetStats(&info));
2386
2387 // We have added one send stream. We should see the stats we've set.
2388 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002389 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002390 // We have added one receive stream. We should see empty stats.
2391 EXPECT_EQ(info.receivers.size(), 1u);
2392 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2393 }
solenberg1ac56142015-10-13 03:58:19 -07002394
solenberg566ef242015-11-06 15:34:49 -08002395 // Start sending - this affects some reported stats.
2396 {
2397 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002398 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002399 EXPECT_EQ(true, channel_->GetStats(&info));
2400 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002401 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002402 }
2403
solenberg2100c0b2017-03-01 11:29:29 -08002404 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002405 {
2406 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002407 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002408 EXPECT_EQ(true, channel_->GetStats(&info));
2409 EXPECT_EQ(1u, info.senders.size());
2410 EXPECT_EQ(0u, info.receivers.size());
2411 }
solenberg1ac56142015-10-13 03:58:19 -07002412
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002413 // Deliver a new packet - a default receive stream should be created and we
2414 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002415 {
2416 cricket::VoiceMediaInfo info;
2417 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2418 SetAudioReceiveStreamStats();
2419 EXPECT_EQ(true, channel_->GetStats(&info));
2420 EXPECT_EQ(1u, info.senders.size());
2421 EXPECT_EQ(1u, info.receivers.size());
2422 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002423 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002424 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425}
2426
2427// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002428// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002430 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002431 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2432 EXPECT_TRUE(AddRecvStream(kSsrcY));
2433 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434}
2435
2436// Test that the local SSRC is the same on sending and receiving channels if the
2437// receive channel is created before the send channel.
2438TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002439 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002440 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002442 cricket::StreamParams::CreateLegacy(kSsrcX)));
2443 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2444 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445}
2446
2447// Test that we can properly receive packets.
2448TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002449 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002450 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002452
2453 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2454 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455}
2456
2457// Test that we can properly receive packets on multiple streams.
2458TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002459 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002460 const uint32_t ssrc1 = 1;
2461 const uint32_t ssrc2 = 2;
2462 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002463 EXPECT_TRUE(AddRecvStream(ssrc1));
2464 EXPECT_TRUE(AddRecvStream(ssrc2));
2465 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002467 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002468 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002470 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 }
mflodman3d7db262016-04-29 00:57:13 -07002472
2473 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2474 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2475 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2476
2477 EXPECT_EQ(s1.received_packets(), 0);
2478 EXPECT_EQ(s2.received_packets(), 0);
2479 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002480
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002482 EXPECT_EQ(s1.received_packets(), 0);
2483 EXPECT_EQ(s2.received_packets(), 0);
2484 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002485
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_EQ(s1.received_packets(), 1);
2488 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2489 EXPECT_EQ(s2.received_packets(), 0);
2490 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002491
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002493 EXPECT_EQ(s1.received_packets(), 1);
2494 EXPECT_EQ(s2.received_packets(), 1);
2495 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2496 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002497
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002499 EXPECT_EQ(s1.received_packets(), 1);
2500 EXPECT_EQ(s2.received_packets(), 1);
2501 EXPECT_EQ(s3.received_packets(), 1);
2502 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002503
mflodman3d7db262016-04-29 00:57:13 -07002504 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2505 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2506 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507}
2508
solenberg2100c0b2017-03-01 11:29:29 -08002509// Test that receiving on an unsignaled stream works (a stream is created).
2510TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002511 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002512 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2513
solenberg7e63ef02015-11-20 00:19:43 -08002514 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002515
2516 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002517 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2518 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002519}
2520
solenberg2100c0b2017-03-01 11:29:29 -08002521// Test that receiving N unsignaled stream works (streams will be created), and
2522// that packets are forwarded to them all.
2523TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002524 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002525 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002526 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2527
solenberg2100c0b2017-03-01 11:29:29 -08002528 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002529 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002530 rtc::SetBE32(&packet[8], ssrc);
2531 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002532
solenberg2100c0b2017-03-01 11:29:29 -08002533 // Verify we have one new stream for each loop iteration.
2534 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2536 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002537 }
mflodman3d7db262016-04-29 00:57:13 -07002538
solenberg2100c0b2017-03-01 11:29:29 -08002539 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002540 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002541 rtc::SetBE32(&packet[8], ssrc);
2542 DeliverPacket(packet, sizeof(packet));
2543
solenbergebb349d2017-03-13 05:46:15 -07002544 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002545 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2546 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2547 }
2548
2549 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2550 constexpr uint32_t kAnotherSsrc = 667;
2551 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002552 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002553
2554 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002555 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002556 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002557 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002558 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2559 EXPECT_EQ(2, streams[i]->received_packets());
2560 }
2561 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2562 EXPECT_EQ(1, streams[i]->received_packets());
2563 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002564 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002565}
2566
solenberg2100c0b2017-03-01 11:29:29 -08002567// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002568// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002569TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002570 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002571 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002572 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2573
2574 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002575 const uint32_t signaled_ssrc = 1;
2576 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002577 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002578 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002579 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2580 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002581 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002582
2583 // Note that the first unknown SSRC cannot be 0, because we only support
2584 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002585 const uint32_t unsignaled_ssrc = 7011;
2586 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002587 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002588 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2589 packet, sizeof(packet)));
2590 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2591
2592 DeliverPacket(packet, sizeof(packet));
2593 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2594
2595 rtc::SetBE32(&packet[8], signaled_ssrc);
2596 DeliverPacket(packet, sizeof(packet));
2597 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2598 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002599}
2600
solenberg4904fb62017-02-17 12:01:14 -08002601// Two tests to verify that adding a receive stream with the same SSRC as a
2602// previously added unsignaled stream will only recreate underlying stream
2603// objects if the stream parameters have changed.
2604TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2605 EXPECT_TRUE(SetupChannel());
2606
2607 // Spawn unsignaled stream with SSRC=1.
2608 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2609 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2610 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2611 sizeof(kPcmuFrame)));
2612
2613 // Verify that the underlying stream object in Call is not recreated when a
2614 // stream with SSRC=1 is added.
2615 const auto& streams = call_.GetAudioReceiveStreams();
2616 EXPECT_EQ(1, streams.size());
2617 int audio_receive_stream_id = streams.front()->id();
2618 EXPECT_TRUE(AddRecvStream(1));
2619 EXPECT_EQ(1, streams.size());
2620 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2621}
2622
2623TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2624 EXPECT_TRUE(SetupChannel());
2625
2626 // Spawn unsignaled stream with SSRC=1.
2627 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2628 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2629 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2630 sizeof(kPcmuFrame)));
2631
2632 // Verify that the underlying stream object in Call *is* recreated when a
2633 // stream with SSRC=1 is added, and which has changed stream parameters.
2634 const auto& streams = call_.GetAudioReceiveStreams();
2635 EXPECT_EQ(1, streams.size());
2636 int audio_receive_stream_id = streams.front()->id();
2637 cricket::StreamParams stream_params;
2638 stream_params.ssrcs.push_back(1);
2639 stream_params.sync_label = "sync_label";
2640 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2641 EXPECT_EQ(1, streams.size());
2642 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2643}
2644
solenberg0a617e22015-10-20 15:49:38 -07002645// Test that we properly handle failures to add a receive stream.
2646TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002649 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002650}
2651
solenberg0a617e22015-10-20 15:49:38 -07002652// Test that we properly handle failures to add a send stream.
2653TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002654 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002655 voe_.set_fail_create_channel(true);
2656 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2657}
2658
solenberg1ac56142015-10-13 03:58:19 -07002659// Test that AddRecvStream creates new stream.
2660TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002661 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002663 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002664 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002665}
2666
2667// Test that after adding a recv stream, we do not decode more codecs than
2668// those previously passed into SetRecvCodecs.
2669TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002670 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002671 cricket::AudioRecvParameters parameters;
2672 parameters.codecs.push_back(kIsacCodec);
2673 parameters.codecs.push_back(kPcmuCodec);
2674 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002675 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002676 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2677 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2678 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002679}
2680
2681// Test that we properly clean up any streams that were added, even if
2682// not explicitly removed.
2683TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002684 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002685 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002686 EXPECT_TRUE(AddRecvStream(1));
2687 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2689 delete channel_;
2690 channel_ = NULL;
2691 EXPECT_EQ(0, voe_.GetNumChannels());
2692}
2693
wu@webrtc.org78187522013-10-07 23:32:02 +00002694TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002695 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002696 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002697}
2698
2699TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002700 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002701 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002702 // Manually delete channel to simulate a failure.
2703 int channel = voe_.GetLastChannel();
2704 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2705 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002706 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002707 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002708 EXPECT_NE(channel, new_channel);
2709 // The last created channel is deleted too.
2710 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002711}
2712
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002713// Test the InsertDtmf on default send stream as caller.
2714TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002715 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716}
2717
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002718// Test the InsertDtmf on default send stream as callee
2719TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002720 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002721}
2722
2723// Test the InsertDtmf on specified send stream as caller.
2724TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002725 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002726}
2727
2728// Test the InsertDtmf on specified send stream as callee.
2729TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002730 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731}
2732
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002734 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002735 EXPECT_CALL(adm_,
2736 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2737 EXPECT_CALL(adm_,
2738 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2739 EXPECT_CALL(adm_,
2740 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002741
solenberg246b8172015-12-08 09:50:23 -08002742 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2743 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744
solenberg246b8172015-12-08 09:50:23 -08002745 // Nothing set in AudioOptions, so everything should be as default.
2746 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002747 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002748 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002749 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2750 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751
2752 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002753 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002755 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757
2758 // Turn echo cancellation back on, with settings, and make sure
2759 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002762 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002763 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002765 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2766 // control.
solenberg76377c52017-02-21 00:54:31 -08002767 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2768 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002769 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002770 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002771
2772 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002773 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2774 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002775 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2776 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2777 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002778 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002779
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002780 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002781 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002783 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002784 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002785
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002787 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2789 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002791 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002792 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793
2794 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002795 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2797 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002799 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2800 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002801 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802
2803 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002804 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2805 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2806 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2807 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2808 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2810 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002811 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2812 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2813 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2814 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002815 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002816 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817
solenberg1ac56142015-10-13 03:58:19 -07002818 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002819 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2820 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2821 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2822 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2823 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2824 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2825 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002826 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827}
2828
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002829TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002830 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002831 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002832 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002833 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002834 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002835 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002836 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002837 EXPECT_CALL(adm_,
2838 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2839 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2840 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002841 webrtc::AudioProcessing::Config apm_config;
2842 EXPECT_CALL(*apm_, GetConfig())
2843 .Times(10)
2844 .WillRepeatedly(ReturnPointee(&apm_config));
2845 EXPECT_CALL(*apm_, ApplyConfig(_))
2846 .Times(10)
2847 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002848 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002849
kwiberg686a8ef2016-02-26 03:00:35 -08002850 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002851 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002852 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002853 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002854 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002855 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856
2857 // Have to add a stream to make SetSend work.
2858 cricket::StreamParams stream1;
2859 stream1.ssrcs.push_back(1);
2860 channel1->AddSendStream(stream1);
2861 cricket::StreamParams stream2;
2862 stream2.ssrcs.push_back(2);
2863 channel2->AddSendStream(stream2);
2864
2865 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002866 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002867 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2868 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2869 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002870 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2871 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2872 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2873 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2874 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002875 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002876 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002877 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002878 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
2880 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002882 parameters_options_no_ns.options.noise_suppression =
2883 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002884 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002889 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002890 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002891 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2892 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2893 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002894 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895
2896 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002897 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002898 parameters_options_no_agc.options.auto_gain_control =
2899 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002900 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2903 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2904 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002905 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002906 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2907 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2908 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002909 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002916 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2920 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2921 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2922 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002923 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924
solenberg76377c52017-02-21 00:54:31 -08002925 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2926 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2927 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2928 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2929 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002930 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002931
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002933 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2934 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002935 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002936 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002937 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002938 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002939 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2940 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2941 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2942 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2943 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002944 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002945 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2946 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2947 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002948 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949}
2950
wu@webrtc.orgde305012013-10-31 15:40:38 +00002951// This test verifies DSCP settings are properly applied on voice media channel.
2952TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002953 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002954 cricket::FakeNetworkInterface network_interface;
2955 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002956 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002957
peahb1c9d1d2017-07-25 15:45:24 -07002958 webrtc::AudioProcessing::Config apm_config;
2959 EXPECT_CALL(*apm_, GetConfig())
2960 .Times(3)
2961 .WillRepeatedly(ReturnPointee(&apm_config));
2962 EXPECT_CALL(*apm_, ApplyConfig(_))
2963 .Times(3)
2964 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002965 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002966
solenbergbc37fc82016-04-04 09:54:44 -07002967 channel.reset(
2968 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002969 channel->SetInterface(&network_interface);
2970 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2971 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2972
2973 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002974 channel.reset(
2975 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002976 channel->SetInterface(&network_interface);
2977 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2978
2979 // Verify that setting the option to false resets the
2980 // DiffServCodePoint.
2981 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002982 channel.reset(
2983 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002984 channel->SetInterface(&network_interface);
2985 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2986 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2987
2988 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002989}
2990
solenberg1ac56142015-10-13 03:58:19 -07002991TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002992 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993 cricket::WebRtcVoiceMediaChannel* media_channel =
2994 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002995 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002996 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002997 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002998 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2999 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3000 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003001 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003}
3004
solenberg1ac56142015-10-13 03:58:19 -07003005TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003006 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003008 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3009 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3010 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003011 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003012 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003013 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3014 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003015 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003016 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003017 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003018 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019}
3020
solenberg4bac9c52015-10-09 02:32:53 -07003021TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003022 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003023 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003025 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003026 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003027 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3028 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3029 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003030}
3031
solenberg2100c0b2017-03-01 11:29:29 -08003032TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003033 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003034
3035 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003036 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003037 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3038
3039 // Should remember the volume "2" which will be set on new unsignaled streams,
3040 // and also set the gain to 2 on existing unsignaled streams.
3041 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3042 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3043
3044 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3045 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3046 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3047 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3048 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3049 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3050
3051 // Setting gain with SSRC=0 should affect all unsignaled streams.
3052 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003053 if (kMaxUnsignaledRecvStreams > 1) {
3054 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3055 }
solenberg2100c0b2017-03-01 11:29:29 -08003056 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3057
3058 // Setting gain on an individual stream affects only that.
3059 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003060 if (kMaxUnsignaledRecvStreams > 1) {
3061 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3062 }
solenberg2100c0b2017-03-01 11:29:29 -08003063 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003064}
3065
pbos8fc7fa72015-07-15 08:02:58 -07003066TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003067 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003068 const std::string kSyncLabel = "AvSyncLabel";
3069
solenbergff976312016-03-30 23:28:51 -07003070 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003071 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3072 sp.sync_label = kSyncLabel;
3073 // Creating two channels to make sure that sync label is set properly for both
3074 // the default voice channel and following ones.
3075 EXPECT_TRUE(channel_->AddRecvStream(sp));
3076 sp.ssrcs[0] += 1;
3077 EXPECT_TRUE(channel_->AddRecvStream(sp));
3078
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003079 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003080 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003081 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003082 << "SyncGroup should be set based on sync_label";
3083 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003084 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003085 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003086}
3087
solenberg3a941542015-11-16 07:34:50 -08003088// TODO(solenberg): Remove, once recv streams are configured through Call.
3089// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003090TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 // Test that setting the header extensions results in the expected state
3092 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003093 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003094 ssrcs.push_back(223);
3095 ssrcs.push_back(224);
3096
solenbergff976312016-03-30 23:28:51 -07003097 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003098 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003099 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003100 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003101 cricket::StreamParams::CreateLegacy(ssrc)));
3102 }
3103
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003104 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003105 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003106 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107 EXPECT_NE(nullptr, s);
3108 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3109 }
3110
3111 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003112 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003113 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003114 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003115 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003116 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003117 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003118 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119 EXPECT_NE(nullptr, s);
3120 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003121 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3122 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123 for (const auto& s_ext : s_exts) {
3124 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003125 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003126 }
3127 }
3128 }
3129 }
3130
3131 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003132 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003133 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003134 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003135 EXPECT_NE(nullptr, s);
3136 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3137 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003138}
3139
3140TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3141 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003142 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003143 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003144 static const unsigned char kRtcp[] = {
3145 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3146 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3149 };
jbaucheec21bd2016-03-20 06:15:43 -07003150 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003151
solenbergff976312016-03-30 23:28:51 -07003152 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003153 cricket::WebRtcVoiceMediaChannel* media_channel =
3154 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003155 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003156 EXPECT_TRUE(media_channel->AddRecvStream(
3157 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3158
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003159 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003160 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003161 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003162 EXPECT_EQ(0, s->received_packets());
3163 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3164 EXPECT_EQ(1, s->received_packets());
3165 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3166 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003167}
Minyue2013aec2015-05-13 14:14:42 +02003168
solenberg0a617e22015-10-20 15:49:38 -07003169// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003170// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003171TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003172 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003173 EXPECT_TRUE(AddRecvStream(kSsrcY));
3174 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003175 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003176 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3177 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3178 EXPECT_TRUE(AddRecvStream(kSsrcW));
3179 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003180}
3181
solenberg7602aab2016-11-14 11:30:07 -08003182TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3183 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003184 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003185 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003186 cricket::StreamParams::CreateLegacy(kSsrcY)));
3187 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3188 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3189 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003190 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003191 cricket::StreamParams::CreateLegacy(kSsrcW)));
3192 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3193 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003194}
stefan658910c2015-09-03 05:48:32 -07003195
deadbeef884f5852016-01-15 09:20:04 -08003196TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003197 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003198 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3199 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003200
3201 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003202 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3203 EXPECT_TRUE(AddRecvStream(kSsrcX));
3204 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003207 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3208 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003209
3210 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003211 channel_->SetRawAudioSink(kSsrcX, nullptr);
3212 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003213}
3214
solenberg2100c0b2017-03-01 11:29:29 -08003215TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003216 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003217 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3218 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003219 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3220 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003221
3222 // Should be able to set a default sink even when no stream exists.
3223 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3224
solenberg2100c0b2017-03-01 11:29:29 -08003225 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3226 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003227 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003228 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003229
3230 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003231 channel_->SetRawAudioSink(kSsrc0, nullptr);
3232 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003233
3234 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003235 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3236 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003237
3238 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003239 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003240 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003241 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3242
3243 // Spawn another unsignaled stream - it should be assigned the default sink
3244 // and the previous unsignaled stream should lose it.
3245 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3246 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3247 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3248 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003249 if (kMaxUnsignaledRecvStreams > 1) {
3250 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3251 }
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3253
3254 // Reset the default sink - the second unsignaled stream should lose it.
3255 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003256 if (kMaxUnsignaledRecvStreams > 1) {
3257 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3258 }
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3260
3261 // Try setting the default sink while two streams exists.
3262 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003263 if (kMaxUnsignaledRecvStreams > 1) {
3264 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3265 }
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3267
3268 // Try setting the sink for the first unsignaled stream using its known SSRC.
3269 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003270 if (kMaxUnsignaledRecvStreams > 1) {
3271 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3272 }
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003274 if (kMaxUnsignaledRecvStreams > 1) {
3275 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3276 }
deadbeef884f5852016-01-15 09:20:04 -08003277}
3278
skvlad7a43d252016-03-22 15:32:27 -07003279// Test that, just like the video channel, the voice channel communicates the
3280// network state to the call.
3281TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003282 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003283
3284 EXPECT_EQ(webrtc::kNetworkUp,
3285 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3286 EXPECT_EQ(webrtc::kNetworkUp,
3287 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3288
3289 channel_->OnReadyToSend(false);
3290 EXPECT_EQ(webrtc::kNetworkDown,
3291 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3292 EXPECT_EQ(webrtc::kNetworkUp,
3293 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3294
3295 channel_->OnReadyToSend(true);
3296 EXPECT_EQ(webrtc::kNetworkUp,
3297 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3298 EXPECT_EQ(webrtc::kNetworkUp,
3299 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3300}
3301
aleloi18e0b672016-10-04 02:45:47 -07003302// Test that playout is still started after changing parameters
3303TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3304 SetupRecvStream();
3305 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003306 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003307
3308 // Changing RTP header extensions will recreate the AudioReceiveStream.
3309 cricket::AudioRecvParameters parameters;
3310 parameters.extensions.push_back(
3311 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3312 channel_->SetRecvParameters(parameters);
3313
solenberg2100c0b2017-03-01 11:29:29 -08003314 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003315}
3316
stefan658910c2015-09-03 05:48:32 -07003317// Tests that the library initializes and shuts down properly.
3318TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003319 // If the VoiceEngine wants to gather available codecs early, that's fine but
3320 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003321 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3322 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003323 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003324 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003325 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003326 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003327 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003328 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003329 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003330 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3331 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003332 EXPECT_TRUE(channel != nullptr);
3333 delete channel;
solenbergff976312016-03-30 23:28:51 -07003334}
stefan658910c2015-09-03 05:48:32 -07003335
solenbergff976312016-03-30 23:28:51 -07003336// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003337TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3338 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3339 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3340 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003341 // Return 100ms just in case this function gets called. If we don't,
3342 // we could enter a tight loop since the mock would return 0.
3343 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003344 {
peaha9cc40b2017-06-29 08:32:09 -07003345 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3346 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003347 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003348 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003349 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003350 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003351 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003352 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003353 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003354 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3355 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3356 EXPECT_TRUE(channel != nullptr);
3357 delete channel;
3358 }
stefan658910c2015-09-03 05:48:32 -07003359}
3360
ossu20a4b3f2017-04-27 02:08:52 -07003361// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3362TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003363 // TODO(ossu): Why are the payload types of codecs with non-static payload
3364 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003365 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3366 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003367 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003368 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003369 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003370 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003371 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003372 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3373 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3374 (clockrate == 0 || codec.clockrate == clockrate);
3375 };
3376 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003382 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003384 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003385 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003386 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003387 EXPECT_EQ(126, codec.id);
3388 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3389 // Remove these checks once both send and receive side assigns payload types
3390 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003391 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003392 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003393 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003394 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003395 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003396 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003397 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(111, codec.id);
3399 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3400 EXPECT_EQ("10", codec.params.find("minptime")->second);
3401 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3402 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003403 }
3404 }
stefan658910c2015-09-03 05:48:32 -07003405}
3406
3407// Tests that VoE supports at least 32 channels
3408TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003409 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3410 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003411 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003412 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003413 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003414 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003415 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003416 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003417 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003418
3419 cricket::VoiceMediaChannel* channels[32];
3420 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003421 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003422 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3423 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003424 if (!channel)
3425 break;
stefan658910c2015-09-03 05:48:32 -07003426 channels[num_channels++] = channel;
3427 }
3428
tfarina5237aaf2015-11-10 23:44:30 -08003429 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003430 EXPECT_EQ(expected, num_channels);
3431
3432 while (num_channels > 0) {
3433 delete channels[--num_channels];
3434 }
stefan658910c2015-09-03 05:48:32 -07003435}
3436
3437// Test that we set our preferred codecs properly.
3438TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003439 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3440 // - Check that our builtin codecs are usable by Channel.
3441 // - The codecs provided by the engine is usable by Channel.
3442 // It does not check that the codecs in the RecvParameters are actually
3443 // what we sent in - though it's probably reasonable to expect so, if
3444 // SetRecvParameters returns true.
3445 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003446 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3447 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003448 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003449 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003450 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003451 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003452 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003453 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003454 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003455 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3456 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003457 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003458 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003459 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003460}
ossu9def8002017-02-09 05:14:32 -08003461
3462TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3463 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003464 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3465 {48000, 2, 16000, 10000, 20000}};
3466 spec1.info.allow_comfort_noise = false;
3467 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003468 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003469 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3470 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003471 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003472 specs.push_back(webrtc::AudioCodecSpec{
3473 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3474 {16000, 1, 13300}});
3475 specs.push_back(
3476 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3477 specs.push_back(
3478 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003479
ossueb1fde42017-05-02 06:46:30 -07003480 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3481 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3482 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003483 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003484 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003485 .WillOnce(Return(specs));
3486
peaha9cc40b2017-06-29 08:32:09 -07003487 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3488 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003489 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003490 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003491 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003492 auto codecs = engine.recv_codecs();
3493 EXPECT_EQ(11, codecs.size());
3494
3495 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3496 // check the actual values safely, to provide better test results.
3497 auto get_codec =
3498 [&codecs](size_t index) -> const cricket::AudioCodec& {
3499 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3500 if (codecs.size() > index)
3501 return codecs[index];
3502 return missing_codec;
3503 };
3504
3505 // Ensure the general codecs are generated first and in order.
3506 for (size_t i = 0; i != specs.size(); ++i) {
3507 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3508 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3509 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3510 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3511 }
3512
3513 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003514 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003515 auto find_codec =
3516 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3517 for (size_t i = 0; i != codecs.size(); ++i) {
3518 const cricket::AudioCodec& codec = codecs[i];
3519 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3520 codec.clockrate == format.clockrate_hz &&
3521 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003522 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003523 }
3524 }
3525 return -1;
3526 };
3527
3528 // Ensure all supplementary codecs are generated last. Their internal ordering
3529 // is not important.
3530 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3531 const int num_specs = static_cast<int>(specs.size());
3532 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3533 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3534 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3535 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3536 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3537 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3538 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3539}