blob: 30396d970de1c9655dc5705d5ec5129816b61078 [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;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200626 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700627 stats.expand_rate = 5.67f;
628 stats.speech_expand_rate = 8.90f;
629 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200630 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700631 stats.accelerate_rate = 4.56f;
632 stats.preemptive_expand_rate = 7.89f;
633 stats.decoding_calls_to_silence_generator = 12;
634 stats.decoding_calls_to_neteq = 345;
635 stats.decoding_normal = 67890;
636 stats.decoding_plc = 1234;
637 stats.decoding_cng = 5678;
638 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700639 stats.decoding_muted_output = 3456;
640 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200641 return stats;
642 }
643 void SetAudioReceiveStreamStats() {
644 for (auto* s : call_.GetAudioReceiveStreams()) {
645 s->SetStats(GetAudioReceiveStreamStats());
646 }
647 }
648 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700649 const auto stats = GetAudioReceiveStreamStats();
650 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
651 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
652 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
653 EXPECT_EQ(info.packets_lost, stats.packets_lost);
654 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
655 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800656 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700657 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
658 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
659 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200660 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700661 stats.jitter_buffer_preferred_ms);
662 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
663 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700664 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
665 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200666 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200667 EXPECT_EQ(info.jitter_buffer_delay_seconds,
668 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700669 EXPECT_EQ(info.expand_rate, stats.expand_rate);
670 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
671 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200672 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
674 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200675 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700676 stats.decoding_calls_to_silence_generator);
677 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
678 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
679 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
680 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
681 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700682 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700683 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200684 }
hbos1acfbd22016-11-17 23:43:29 -0800685 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
686 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
687 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
688 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
689 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
690 codec.ToCodecParameters());
691 }
692 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
693 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
694 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
695 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
696 codec.ToCodecParameters());
697 }
698 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200699
peah8271d042016-11-22 07:24:52 -0800700 bool IsHighPassFilterEnabled() {
701 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
702 }
703
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700705 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700706 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800707 webrtc::test::MockGainControl& apm_gc_;
708 webrtc::test::MockEchoCancellation& apm_ec_;
709 webrtc::test::MockNoiseSuppression& apm_ns_;
710 webrtc::test::MockVoiceDetection& apm_vd_;
711 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700712 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200713 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700715 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700716 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200717 cricket::AudioSendParameters send_parameters_;
718 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800719 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700720 webrtc::AudioProcessing::Config apm_config_;
721
stefanba4c0e42016-02-04 04:12:24 -0800722 private:
723 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724};
725
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726// Tests that we can create and destroy a channel.
727TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700728 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729}
730
solenberg31fec402016-05-06 02:13:12 -0700731// Test that we can add a send stream and that it has the correct defaults.
732TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
733 EXPECT_TRUE(SetupChannel());
734 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800735 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
736 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
737 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700738 EXPECT_EQ("", config.rtp.c_name);
739 EXPECT_EQ(0u, config.rtp.extensions.size());
740 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
741 config.send_transport);
742}
743
744// Test that we can add a receive stream and that it has the correct defaults.
745TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
746 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800747 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700748 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800749 GetRecvStreamConfig(kSsrcX);
750 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700751 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
752 EXPECT_FALSE(config.rtp.transport_cc);
753 EXPECT_EQ(0u, config.rtp.extensions.size());
754 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
755 config.rtcp_send_transport);
756 EXPECT_EQ("", config.sync_group);
757}
758
stefanba4c0e42016-02-04 04:12:24 -0800759TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700760 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800761 bool opus_found = false;
762 for (cricket::AudioCodec codec : codecs) {
763 if (codec.name == "opus") {
764 EXPECT_TRUE(HasTransportCc(codec));
765 opus_found = true;
766 }
767 }
768 EXPECT_TRUE(opus_found);
769}
770
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771// Test that we set our inbound codecs properly, including changing PT.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800777 parameters.codecs.push_back(kTelephoneEventCodec1);
778 parameters.codecs.push_back(kTelephoneEventCodec2);
779 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200780 parameters.codecs[2].id = 126;
781 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800782 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700783 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
784 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
785 {{0, {"PCMU", 8000, 1}},
786 {106, {"ISAC", 16000, 1}},
787 {126, {"telephone-event", 8000, 1}},
788 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail to set an unknown inbound codec.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700796 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798}
799
800// Test that we fail if we have duplicate types in the inbound list.
801TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700802 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200803 cricket::AudioRecvParameters parameters;
804 parameters.codecs.push_back(kIsacCodec);
805 parameters.codecs.push_back(kCn16000Codec);
806 parameters.codecs[1].id = kIsacCodec.id;
807 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that we can decode OPUS without stereo parameters.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
816 parameters.codecs.push_back(kOpusCodec);
817 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800818 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700819 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
820 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
821 {{0, {"PCMU", 8000, 1}},
822 {103, {"ISAC", 16000, 1}},
823 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS with stereo = 0.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 parameters.codecs[2].params["stereo"] = "0";
834 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800835 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700836 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
837 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
838 {{0, {"PCMU", 8000, 1}},
839 {103, {"ISAC", 16000, 1}},
840 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can decode OPUS with stereo = 1.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kPcmuCodec);
849 parameters.codecs.push_back(kOpusCodec);
850 parameters.codecs[2].params["stereo"] = "1";
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700853 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
854 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
855 {{0, {"PCMU", 8000, 1}},
856 {103, {"ISAC", 16000, 1}},
857 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that changes to recv codecs are applied to all streams.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800866 parameters.codecs.push_back(kTelephoneEventCodec1);
867 parameters.codecs.push_back(kTelephoneEventCodec2);
868 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200869 parameters.codecs[2].id = 126;
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700871 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
872 EXPECT_TRUE(AddRecvStream(ssrc));
873 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
874 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
875 {{0, {"PCMU", 8000, 1}},
876 {106, {"ISAC", 16000, 1}},
877 {126, {"telephone-event", 8000, 1}},
878 {107, {"telephone-event", 32000, 1}}})));
879 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800886 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
solenberg2100c0b2017-03-01 11:29:29 -0800889 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800890 ASSERT_EQ(1, dm.count(106));
891 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894// Test that we can apply the same set of codecs again while playing.
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
899 parameters.codecs.push_back(kCn16000Codec);
900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700901 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
deadbeefcb383672017-04-26 16:28:42 -0700904 // Remapping a payload type to a different codec should fail.
905 parameters.codecs[0] = kOpusCodec;
906 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800908 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can add a codec while playing.
912TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kCn16000Codec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700918 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 parameters.codecs.push_back(kOpusCodec);
921 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800922 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
deadbeefcb383672017-04-26 16:28:42 -0700925// Test that we accept adding the same codec with a different payload type.
926// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
927TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
928 EXPECT_TRUE(SetupRecvStream());
929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932
933 ++parameters.codecs[0].id;
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
935}
936
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 // Test that when autobw is enabled, bitrate is kept as the default
941 // value. autobw is enabled for the following tests because the target
942 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
947 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700948 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
ossu20a4b3f2017-04-27 02:08:52 -0700950 // opus, default bitrate == 32000 in mono.
951 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
959 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700960 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
964 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
965 // Rates above the max (510000) should be capped.
966 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971
972 // Test that we can only set a maximum bitrate for a fixed-rate codec
973 // if it's bigger than the fixed rate.
974
975 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983}
984
985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 const int kDesiredBitrate = 128000;
988 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700989 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200990 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700991 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
993 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800994 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000995
solenberg2100c0b2017-03-01 11:29:29 -0800996 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000997}
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999// Test that bitrate cannot be set for CBR codecs.
1000// Bitrate is ignored if it is higher than the fixed bitrate.
1001// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008
1009 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001010 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001012
1013 send_parameters_.max_bandwidth_bps = 128;
1014 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016}
1017
skvlade0d46372016-04-07 22:59:22 -07001018// Test that the per-stream bitrate limit and the global
1019// bitrate limit both apply.
1020TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1021 EXPECT_TRUE(SetupSendStream());
1022
ossu20a4b3f2017-04-27 02:08:52 -07001023 // opus, default bitrate == 32000.
1024 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001025 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1028
1029 // CBR codecs allow both maximums to exceed the bitrate.
1030 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1031 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1034
1035 // CBR codecs don't allow per stream maximums to be too low.
1036 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1037 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1038}
1039
1040// Test that an attempt to set RtpParameters for a stream that does not exist
1041// fails.
1042TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1043 EXPECT_TRUE(SetupChannel());
1044 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001045 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001046 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1047
1048 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001049 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001050}
1051
1052TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001053 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001054 // This test verifies that setting RtpParameters succeeds only if
1055 // the structure contains exactly one encoding.
1056 // TODO(skvlad): Update this test when we start supporting setting parameters
1057 // for each encoding individually.
1058
1059 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001060 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001061 // Two or more encodings should result in failure.
1062 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001064 // Zero encodings should also fail.
1065 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001067}
1068
1069// Changing the SSRC through RtpParameters is not allowed.
1070TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1071 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001072 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001073 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001074 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001075}
1076
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001077// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001078// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1080 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001081 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001082 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001083 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001084 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085 ASSERT_EQ(1u, parameters.encodings.size());
1086 ASSERT_TRUE(parameters.encodings[0].active);
1087 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001088 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001090
1091 // Now change it back to active and verify we resume sending.
1092 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001093 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095}
1096
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097// Test that SetRtpSendParameters configures the correct encoding channel for
1098// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001099TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1100 SetupForMultiSendStream();
1101 // Create send streams.
1102 for (uint32_t ssrc : kSsrcs4) {
1103 EXPECT_TRUE(
1104 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1105 }
1106 // Configure one stream to be limited by the stream config, another to be
1107 // limited by the global max, and the third one with no per-stream limit
1108 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001109 SetGlobalMaxBitrate(kOpusCodec, 32000);
1110 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1111 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001112 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1113
ossu20a4b3f2017-04-27 02:08:52 -07001114 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1115 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1116 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001117
1118 // Remove the global cap; the streams should switch to their respective
1119 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001120 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001121 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1122 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1123 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001124}
1125
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001126// Test that GetRtpSendParameters returns the currently configured codecs.
1127TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001128 EXPECT_TRUE(SetupSendStream());
1129 cricket::AudioSendParameters parameters;
1130 parameters.codecs.push_back(kIsacCodec);
1131 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001132 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001133
solenberg2100c0b2017-03-01 11:29:29 -08001134 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001136 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1137 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138}
1139
deadbeefcb443432016-12-12 11:12:36 -08001140// Test that GetRtpSendParameters returns an SSRC.
1141TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1142 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001144 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001145 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001146}
1147
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001149TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 EXPECT_TRUE(SetupSendStream());
1151 cricket::AudioSendParameters parameters;
1152 parameters.codecs.push_back(kIsacCodec);
1153 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001154 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155
solenberg2100c0b2017-03-01 11:29:29 -08001156 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157
1158 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001159 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001160
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001161 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001162 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1163 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164}
1165
minyuececec102017-03-27 13:04:25 -07001166// Test that max_bitrate_bps in send stream config gets updated correctly when
1167// SetRtpSendParameters is called.
1168TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1169 webrtc::test::ScopedFieldTrials override_field_trials(
1170 "WebRTC-Audio-SendSideBwe/Enabled/");
1171 EXPECT_TRUE(SetupSendStream());
1172 cricket::AudioSendParameters send_parameters;
1173 send_parameters.codecs.push_back(kOpusCodec);
1174 SetSendParameters(send_parameters);
1175
1176 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1177 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1178 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1179
1180 constexpr int kMaxBitrateBps = 6000;
1181 rtp_parameters.encodings[0].max_bitrate_bps =
1182 rtc::Optional<int>(kMaxBitrateBps);
1183 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1184
1185 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1186 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1187}
1188
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001189// Test that GetRtpReceiveParameters returns the currently configured codecs.
1190TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1191 EXPECT_TRUE(SetupRecvStream());
1192 cricket::AudioRecvParameters parameters;
1193 parameters.codecs.push_back(kIsacCodec);
1194 parameters.codecs.push_back(kPcmuCodec);
1195 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1196
1197 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001198 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1200 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1201 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1202}
1203
deadbeefcb443432016-12-12 11:12:36 -08001204// Test that GetRtpReceiveParameters returns an SSRC.
1205TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1206 EXPECT_TRUE(SetupRecvStream());
1207 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001208 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001209 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001210 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001211}
1212
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213// Test that if we set/get parameters multiple times, we get the same results.
1214TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1215 EXPECT_TRUE(SetupRecvStream());
1216 cricket::AudioRecvParameters parameters;
1217 parameters.codecs.push_back(kIsacCodec);
1218 parameters.codecs.push_back(kPcmuCodec);
1219 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1220
1221 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001222 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223
1224 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001225 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001226
1227 // ... And this shouldn't change the params returned by
1228 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001229 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1230 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001231}
1232
deadbeef3bc15102017-04-20 19:25:07 -07001233// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1234// aren't signaled. It should return an empty "RtpEncodingParameters" when
1235// configured to receive an unsignaled stream and no packets have been received
1236// yet, and start returning the SSRC once a packet has been received.
1237TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1238 ASSERT_TRUE(SetupChannel());
1239 // Call necessary methods to configure receiving a default stream as
1240 // soon as it arrives.
1241 cricket::AudioRecvParameters parameters;
1242 parameters.codecs.push_back(kIsacCodec);
1243 parameters.codecs.push_back(kPcmuCodec);
1244 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1245
1246 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1247 // stream. Should return nothing.
1248 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1249
1250 // Set a sink for an unsignaled stream.
1251 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1252 // Value of "0" means "unsignaled stream".
1253 channel_->SetRawAudioSink(0, std::move(fake_sink));
1254
1255 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1256 // in this method means "unsignaled stream".
1257 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1258 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1259 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1260
1261 // Receive PCMU packet (SSRC=1).
1262 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1263
1264 // The |ssrc| member should still be unset.
1265 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1266 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1267 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1268}
1269
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001270// Test that we apply codecs properly.
1271TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001272 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 cricket::AudioSendParameters parameters;
1274 parameters.codecs.push_back(kIsacCodec);
1275 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001276 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001277 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001278 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001279 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001280 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1281 EXPECT_EQ(96, send_codec_spec.payload_type);
1282 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1283 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1284 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1285 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001286 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001287}
1288
ossu20a4b3f2017-04-27 02:08:52 -07001289// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1290// AudioSendStream.
1291TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001292 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001293 cricket::AudioSendParameters parameters;
1294 parameters.codecs.push_back(kIsacCodec);
1295 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001296 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001297 parameters.codecs[0].id = 96;
1298 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001299 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001300 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001301 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001302 // Calling SetSendCodec again with same codec which is already set.
1303 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001304 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001305 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001306}
1307
ossu20a4b3f2017-04-27 02:08:52 -07001308// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1309// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001310
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001311// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001313 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001314 cricket::AudioSendParameters parameters;
1315 parameters.codecs.push_back(kOpusCodec);
1316 parameters.codecs[0].bitrate = 0;
1317 parameters.codecs[0].clockrate = 50000;
1318 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319}
1320
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001321// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001323 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001324 cricket::AudioSendParameters parameters;
1325 parameters.codecs.push_back(kOpusCodec);
1326 parameters.codecs[0].bitrate = 0;
1327 parameters.codecs[0].channels = 0;
1328 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329}
1330
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001331// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001333 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001334 cricket::AudioSendParameters parameters;
1335 parameters.codecs.push_back(kOpusCodec);
1336 parameters.codecs[0].bitrate = 0;
1337 parameters.codecs[0].channels = 0;
1338 parameters.codecs[0].params["stereo"] = "1";
1339 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340}
1341
1342// Test that if channel is 1 for opus and there's no stereo, we fail.
1343TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001344 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001345 cricket::AudioSendParameters parameters;
1346 parameters.codecs.push_back(kOpusCodec);
1347 parameters.codecs[0].bitrate = 0;
1348 parameters.codecs[0].channels = 1;
1349 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350}
1351
1352// Test that if channel is 1 for opus and stereo=0, we fail.
1353TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001354 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 cricket::AudioSendParameters parameters;
1356 parameters.codecs.push_back(kOpusCodec);
1357 parameters.codecs[0].bitrate = 0;
1358 parameters.codecs[0].channels = 1;
1359 parameters.codecs[0].params["stereo"] = "0";
1360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361}
1362
1363// Test that if channel is 1 for opus and stereo=1, we fail.
1364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kOpusCodec);
1368 parameters.codecs[0].bitrate = 0;
1369 parameters.codecs[0].channels = 1;
1370 parameters.codecs[0].params["stereo"] = "1";
1371 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372}
1373
ossu20a4b3f2017-04-27 02:08:52 -07001374// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001376 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 cricket::AudioSendParameters parameters;
1378 parameters.codecs.push_back(kOpusCodec);
1379 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001380 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001381 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382}
1383
ossu20a4b3f2017-04-27 02:08:52 -07001384// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001391 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001392 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393}
1394
ossu20a4b3f2017-04-27 02:08:52 -07001395// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001401 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001403 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001404 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001405
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001406 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001407 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001408 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001409}
1410
ossu20a4b3f2017-04-27 02:08:52 -07001411// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001413 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 cricket::AudioSendParameters parameters;
1415 parameters.codecs.push_back(kOpusCodec);
1416 parameters.codecs[0].bitrate = 0;
1417 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001419 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001420}
1421
ossu20a4b3f2017-04-27 02:08:52 -07001422// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kOpusCodec);
1427 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001428 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001430 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001431 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001432
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001433 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001436}
1437
ossu20a4b3f2017-04-27 02:08:52 -07001438// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1446 EXPECT_EQ(111, spec.payload_type);
1447 EXPECT_EQ(96000, spec.target_bitrate_bps);
1448 EXPECT_EQ("opus", spec.format.name);
1449 EXPECT_EQ(2, spec.format.num_channels);
1450 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
ossu20a4b3f2017-04-27 02:08:52 -07001453// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 30000;
1459 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001461 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462}
1463
ossu20a4b3f2017-04-27 02:08:52 -07001464// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001466 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 cricket::AudioSendParameters parameters;
1468 parameters.codecs.push_back(kOpusCodec);
1469 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001470 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001471 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472}
1473
ossu20a4b3f2017-04-27 02:08:52 -07001474// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001476 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 cricket::AudioSendParameters parameters;
1478 parameters.codecs.push_back(kOpusCodec);
1479 parameters.codecs[0].bitrate = 30000;
1480 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001481 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001482 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001483}
1484
stefan13f1a0a2016-11-30 07:22:58 -08001485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1486 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1487 200000);
1488}
1489
1490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1491 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1492}
1493
1494TEST_F(WebRtcVoiceEngineTestFake,
1495 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1496 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1497}
1498
1499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1500 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1501}
1502
1503TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001504 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001505 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1506 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001507 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001508 SetSendParameters(send_parameters_);
1509 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1510 << "Setting max bitrate should keep previous min bitrate.";
1511 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1512 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001513 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001514}
1515
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001516// Test that we can enable NACK with opus as caller.
1517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].AddFeedbackParam(
1522 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1523 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001524 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001526 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001529// Test that we can enable NACK with opus as callee.
1530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 cricket::AudioSendParameters parameters;
1533 parameters.codecs.push_back(kOpusCodec);
1534 parameters.codecs[0].AddFeedbackParam(
1535 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1536 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001538 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001539 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001541
1542 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001543 cricket::StreamParams::CreateLegacy(kSsrcX)));
1544 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001545}
1546
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547// Test that we can enable NACK on receive streams.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001550 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].AddFeedbackParam(
1554 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1555 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1557 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001558 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1560 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561}
1562
1563// Test that we can disable NACK.
1564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001565 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].AddFeedbackParam(
1569 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1570 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001571 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001574 parameters.codecs.clear();
1575 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578}
1579
1580// Test that we can disable NACK on receive streams.
1581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001583 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001584 cricket::AudioSendParameters parameters;
1585 parameters.codecs.push_back(kOpusCodec);
1586 parameters.codecs[0].AddFeedbackParam(
1587 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1588 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1591 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 parameters.codecs.clear();
1594 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001595 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001596 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1597 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598}
1599
1600// Test that NACK is enabled on a new receive stream.
1601TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001602 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001603 cricket::AudioSendParameters parameters;
1604 parameters.codecs.push_back(kIsacCodec);
1605 parameters.codecs.push_back(kCn16000Codec);
1606 parameters.codecs[0].AddFeedbackParam(
1607 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1608 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_TRUE(AddRecvStream(kSsrcY));
1613 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1614 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1615 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616}
1617
stefanba4c0e42016-02-04 04:12:24 -08001618TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001619 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001620 cricket::AudioSendParameters send_parameters;
1621 send_parameters.codecs.push_back(kOpusCodec);
1622 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001624
1625 cricket::AudioRecvParameters recv_parameters;
1626 recv_parameters.codecs.push_back(kIsacCodec);
1627 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_TRUE(AddRecvStream(kSsrcX));
1629 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001630 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001631 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001632
ossudedfd282016-06-14 07:12:39 -07001633 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001635 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001636 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001637 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001638}
1639
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001640// Test that we can switch back and forth between Opus and ISAC with CN.
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001642 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001643
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters opus_parameters;
1645 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001647 {
ossu20a4b3f2017-04-27 02:08:52 -07001648 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1649 EXPECT_EQ(111, spec.payload_type);
1650 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001651 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001652
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 cricket::AudioSendParameters isac_parameters;
1654 isac_parameters.codecs.push_back(kIsacCodec);
1655 isac_parameters.codecs.push_back(kCn16000Codec);
1656 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001658 {
ossu20a4b3f2017-04-27 02:08:52 -07001659 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1660 EXPECT_EQ(103, spec.payload_type);
1661 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001662 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001663
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001665 {
ossu20a4b3f2017-04-27 02:08:52 -07001666 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1667 EXPECT_EQ(111, spec.payload_type);
1668 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001669 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670}
1671
1672// Test that we handle various ways of specifying bitrate.
1673TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001674 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001675 cricket::AudioSendParameters parameters;
1676 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001678 {
ossu20a4b3f2017-04-27 02:08:52 -07001679 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1680 EXPECT_EQ(103, spec.payload_type);
1681 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1682 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001687 {
ossu20a4b3f2017-04-27 02:08:52 -07001688 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1689 EXPECT_EQ(103, spec.payload_type);
1690 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1691 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001692 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001695 {
ossu20a4b3f2017-04-27 02:08:52 -07001696 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1697 EXPECT_EQ(103, spec.payload_type);
1698 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1699 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001700 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001704 {
ossu20a4b3f2017-04-27 02:08:52 -07001705 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1706 EXPECT_EQ(0, spec.payload_type);
1707 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1708 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001710
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001713 {
ossu20a4b3f2017-04-27 02:08:52 -07001714 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1715 EXPECT_EQ(0, spec.payload_type);
1716 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1717 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001718 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 parameters.codecs[0] = kOpusCodec;
1721 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001723 {
ossu20a4b3f2017-04-27 02:08:52 -07001724 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1725 EXPECT_EQ(111, spec.payload_type);
1726 EXPECT_STREQ("opus", spec.format.name.c_str());
1727 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001728 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729}
1730
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001731// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001733 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 cricket::AudioSendParameters parameters;
1735 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001736}
1737
1738// Test that we can set send codecs even with telephone-event codec as the first
1739// one on the list.
1740TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001741 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001743 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 parameters.codecs.push_back(kIsacCodec);
1745 parameters.codecs.push_back(kPcmuCodec);
1746 parameters.codecs[0].id = 98; // DTMF
1747 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001749 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1750 EXPECT_EQ(96, spec.payload_type);
1751 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001752 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001753}
1754
solenberg31642aa2016-03-14 08:00:37 -07001755// Test that payload type range is limited for telephone-event codec.
1756TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001757 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001758 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001759 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001760 parameters.codecs.push_back(kIsacCodec);
1761 parameters.codecs[0].id = 0; // DTMF
1762 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001763 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001764 EXPECT_TRUE(channel_->CanInsertDtmf());
1765 parameters.codecs[0].id = 128; // DTMF
1766 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1767 EXPECT_FALSE(channel_->CanInsertDtmf());
1768 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001770 EXPECT_TRUE(channel_->CanInsertDtmf());
1771 parameters.codecs[0].id = -1; // DTMF
1772 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1773 EXPECT_FALSE(channel_->CanInsertDtmf());
1774}
1775
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001776// Test that we can set send codecs even with CN codec as the first
1777// one on the list.
1778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001779 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001780 cricket::AudioSendParameters parameters;
1781 parameters.codecs.push_back(kCn16000Codec);
1782 parameters.codecs.push_back(kIsacCodec);
1783 parameters.codecs.push_back(kPcmuCodec);
1784 parameters.codecs[0].id = 98; // wideband CN
1785 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001787 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1788 EXPECT_EQ(96, send_codec_spec.payload_type);
1789 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001790 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001791}
1792
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001793// Test that we set VAD and DTMF types correctly as caller.
1794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001795 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 cricket::AudioSendParameters parameters;
1797 parameters.codecs.push_back(kIsacCodec);
1798 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001799 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 parameters.codecs.push_back(kCn16000Codec);
1801 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001802 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 parameters.codecs[0].id = 96;
1804 parameters.codecs[2].id = 97; // wideband CN
1805 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001807 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1808 EXPECT_EQ(96, send_codec_spec.payload_type);
1809 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1810 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001811 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001812 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813}
1814
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001815// Test that we set VAD and DTMF types correctly as callee.
1816TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 cricket::AudioSendParameters parameters;
1819 parameters.codecs.push_back(kIsacCodec);
1820 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001821 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 parameters.codecs.push_back(kCn16000Codec);
1823 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001824 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs[0].id = 96;
1826 parameters.codecs[2].id = 97; // wideband CN
1827 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001829 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001830 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001831
ossu20a4b3f2017-04-27 02:08:52 -07001832 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1833 EXPECT_EQ(96, send_codec_spec.payload_type);
1834 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1835 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001837 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001838}
1839
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840// Test that we only apply VAD if we have a CN codec that matches the
1841// send codec clockrate.
1842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001843 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001845 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001846 parameters.codecs.push_back(kIsacCodec);
1847 parameters.codecs.push_back(kCn16000Codec);
1848 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001849 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001850 {
ossu20a4b3f2017-04-27 02:08:52 -07001851 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1852 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1853 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001854 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001855 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001856 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001857 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001858 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001859 {
ossu20a4b3f2017-04-27 02:08:52 -07001860 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1861 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1862 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001863 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001865 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001866 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001867 {
ossu20a4b3f2017-04-27 02:08:52 -07001868 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1869 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1870 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001871 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001872 }
Brave Yao5225dd82015-03-26 07:39:19 +08001873 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001874 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001875 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001876 {
ossu20a4b3f2017-04-27 02:08:52 -07001877 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1878 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1879 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001880 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001881}
1882
1883// Test that we perform case-insensitive matching of codec names.
1884TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001885 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 cricket::AudioSendParameters parameters;
1887 parameters.codecs.push_back(kIsacCodec);
1888 parameters.codecs.push_back(kPcmuCodec);
1889 parameters.codecs.push_back(kCn16000Codec);
1890 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001891 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 parameters.codecs[0].name = "iSaC";
1893 parameters.codecs[0].id = 96;
1894 parameters.codecs[2].id = 97; // wideband CN
1895 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001896 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001897 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1898 EXPECT_EQ(96, send_codec_spec.payload_type);
1899 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1900 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001901 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001902 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001903}
1904
stefanba4c0e42016-02-04 04:12:24 -08001905class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1906 public:
1907 WebRtcVoiceEngineWithSendSideBweTest()
1908 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1909};
1910
1911TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1912 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001913 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001914 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001915 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1916 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1917 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001918 extension.id);
1919 return;
1920 }
1921 }
1922 FAIL() << "Transport sequence number extension not in header-extension list.";
1923}
1924
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001925// Test support for audio level header extension.
1926TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001927 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001928}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001929TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001930 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001931}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001932
solenbergd4adce42016-11-17 06:26:52 -08001933// Test support for transport sequence number header extension.
1934TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1935 TestSetSendRtpHeaderExtensions(
1936 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001937}
solenbergd4adce42016-11-17 06:26:52 -08001938TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1939 TestSetRecvRtpHeaderExtensions(
1940 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001941}
1942
solenberg1ac56142015-10-13 03:58:19 -07001943// Test that we can create a channel and start sending on it.
1944TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001945 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001946 SetSendParameters(send_parameters_);
1947 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001948 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001949 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001950 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001951}
1952
1953// Test that a channel will send if and only if it has a source and is enabled
1954// for sending.
1955TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001956 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001957 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001958 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001959 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001960 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1961 SetAudioSend(kSsrcX, true, &fake_source_);
1962 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1963 SetAudioSend(kSsrcX, true, nullptr);
1964 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001965}
1966
solenberg94218532016-06-16 10:53:22 -07001967// Test that a channel is muted/unmuted.
1968TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1969 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001971 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1972 SetAudioSend(kSsrcX, true, nullptr);
1973 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1974 SetAudioSend(kSsrcX, false, nullptr);
1975 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001976}
1977
solenberg6d6e7c52016-04-13 09:07:30 -07001978// Test that SetSendParameters() does not alter a stream's send state.
1979TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1980 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001981 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001982
1983 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001984 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001986
1987 // Changing RTP header extensions will recreate the AudioSendStream.
1988 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001989 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001990 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001991 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001992
1993 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001994 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996
1997 // Changing RTP header extensions will recreate the AudioSendStream.
1998 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001999 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002000 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002001}
2002
solenberg1ac56142015-10-13 03:58:19 -07002003// Test that we can create a channel and start playing out on it.
2004TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002005 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002006 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002007 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002008 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002009 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002010 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002011}
2012
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013// Test that we can add and remove send streams.
2014TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2015 SetupForMultiSendStream();
2016
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002017 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002018 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019
solenbergc96df772015-10-21 13:01:53 -07002020 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002022 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002023 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002024 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002025 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002026 }
tfarina5237aaf2015-11-10 23:44:30 -08002027 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002028
solenbergc96df772015-10-21 13:01:53 -07002029 // Delete the send streams.
2030 for (uint32_t ssrc : kSsrcs4) {
2031 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002032 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002033 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034 }
solenbergc96df772015-10-21 13:01:53 -07002035 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036}
2037
2038// Test SetSendCodecs correctly configure the codecs in all send streams.
2039TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2040 SetupForMultiSendStream();
2041
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002043 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002045 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 }
2047
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002048 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002050 parameters.codecs.push_back(kIsacCodec);
2051 parameters.codecs.push_back(kCn16000Codec);
2052 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002053 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054
2055 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002056 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002057 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2058 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002059 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2060 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2061 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002062 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 }
2064
minyue7a973442016-10-20 03:27:12 -07002065 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002066 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002068 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002069 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2070 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002071 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2072 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2073 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002074 }
2075}
2076
2077// Test we can SetSend on all send streams correctly.
2078TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2079 SetupForMultiSendStream();
2080
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002081 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002082 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002084 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002085 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002086 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 }
2088
2089 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002090 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002091 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002092 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002093 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 }
2095
2096 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002097 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002098 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002100 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 }
2102}
2103
2104// Test we can set the correct statistics on all send streams.
2105TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2106 SetupForMultiSendStream();
2107
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002109 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002111 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 }
solenberg85a04962015-10-27 03:35:21 -07002113
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002114 // Create a receive stream to check that none of the send streams end up in
2115 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002117
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002120 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002121 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122
solenberg85a04962015-10-27 03:35:21 -07002123 // Check stats for the added streams.
2124 {
2125 cricket::VoiceMediaInfo info;
2126 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127
solenberg85a04962015-10-27 03:35:21 -07002128 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002129 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002130 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002131 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002132 }
hbos1acfbd22016-11-17 23:43:29 -08002133 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002134
2135 // We have added one receive stream. We should see empty stats.
2136 EXPECT_EQ(info.receivers.size(), 1u);
2137 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 }
solenberg1ac56142015-10-13 03:58:19 -07002139
solenberg2100c0b2017-03-01 11:29:29 -08002140 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002141 {
2142 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002143 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002144 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002145 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002146 EXPECT_EQ(0u, info.receivers.size());
2147 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002148
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002149 // Deliver a new packet - a default receive stream should be created and we
2150 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002151 {
2152 cricket::VoiceMediaInfo info;
2153 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2154 SetAudioReceiveStreamStats();
2155 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002156 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002157 EXPECT_EQ(1u, info.receivers.size());
2158 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002159 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002160 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161}
2162
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163// Test that we can add and remove receive streams, and do proper send/playout.
2164// We can receive on multiple streams while sending one stream.
2165TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002166 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167
solenberg1ac56142015-10-13 03:58:19 -07002168 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002169 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002170 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171
solenberg1ac56142015-10-13 03:58:19 -07002172 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002173 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002174 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002175 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002176
solenberg1ac56142015-10-13 03:58:19 -07002177 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002178 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002179
2180 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002181 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2182 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2183 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184
2185 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002186 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188
2189 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002190 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002191 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2192 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
aleloi84ef6152016-08-04 05:28:21 -07002194 // Restart playout and make sure recv streams are played out.
2195 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002196 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2197 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198
aleloi84ef6152016-08-04 05:28:21 -07002199 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002200 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2201 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202}
2203
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002205// and start sending on it.
2206TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002207 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002208 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2209 EXPECT_CALL(apm_gc_,
2210 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002211 SetSendParameters(send_parameters_);
2212 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002213 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002214 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002215 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216}
2217
wu@webrtc.org97077a32013-10-25 21:18:33 +00002218TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002219 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002220 EXPECT_CALL(adm_,
2221 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002222 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2223 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002224 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2225 send_parameters_.options.tx_agc_digital_compression_gain =
2226 rtc::Optional<uint16_t>(9);
2227 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2228 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002229 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2230 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2231 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002232 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002233
2234 // Check interaction with adjust_agc_delta. Both should be respected, for
2235 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002236 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002237 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002238 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002239}
2240
wu@webrtc.org97077a32013-10-25 21:18:33 +00002241TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002242 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002243 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2244 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002245 send_parameters_.options.recording_sample_rate =
2246 rtc::Optional<uint32_t>(48000);
2247 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002248 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002249}
2250
minyue6b825df2016-10-31 04:08:32 -07002251TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2252 EXPECT_TRUE(SetupSendStream());
2253 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2254 send_parameters_.options.audio_network_adaptor_config =
2255 rtc::Optional<std::string>("1234");
2256 SetSendParameters(send_parameters_);
2257 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002258 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002259}
2260
2261TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2262 EXPECT_TRUE(SetupSendStream());
2263 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2264 send_parameters_.options.audio_network_adaptor_config =
2265 rtc::Optional<std::string>("1234");
2266 SetSendParameters(send_parameters_);
2267 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002268 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002269 cricket::AudioOptions options;
2270 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002271 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002272 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002273}
2274
2275TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2276 EXPECT_TRUE(SetupSendStream());
2277 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2278 send_parameters_.options.audio_network_adaptor_config =
2279 rtc::Optional<std::string>("1234");
2280 SetSendParameters(send_parameters_);
2281 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002282 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002283 const int initial_num = call_.GetNumCreatedSendStreams();
2284 cricket::AudioOptions options;
2285 options.audio_network_adaptor = rtc::Optional<bool>();
2286 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2287 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002288 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002289 // AudioSendStream not expected to be recreated.
2290 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2291 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002292 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002293}
2294
michaelt6672b262017-01-11 10:17:59 -08002295class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2296 : public WebRtcVoiceEngineTestFake {
2297 public:
2298 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2299 : WebRtcVoiceEngineTestFake(
2300 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2301 "Enabled/") {}
2302};
2303
2304TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2305 EXPECT_TRUE(SetupSendStream());
2306 cricket::AudioSendParameters parameters;
2307 parameters.codecs.push_back(kOpusCodec);
2308 SetSendParameters(parameters);
2309 const int initial_num = call_.GetNumCreatedSendStreams();
2310 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2311
2312 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2313 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002314 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2315 constexpr int kMinOverheadBps =
2316 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002317
2318 constexpr int kOpusMinBitrateBps = 6000;
2319 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002320 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002321 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002322 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002323 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002324
2325 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2326 parameters.options.audio_network_adaptor_config =
2327 rtc::Optional<std::string>("1234");
2328 SetSendParameters(parameters);
2329
ossu11bfc532017-02-16 05:37:06 -08002330 constexpr int kMinOverheadWithAnaBps =
2331 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002332
2333 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002335
minyuececec102017-03-27 13:04:25 -07002336 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002337 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002338}
2339
minyuececec102017-03-27 13:04:25 -07002340// This test is similar to
2341// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2342// additional field trial.
2343TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2344 SetRtpSendParameterUpdatesMaxBitrate) {
2345 EXPECT_TRUE(SetupSendStream());
2346 cricket::AudioSendParameters send_parameters;
2347 send_parameters.codecs.push_back(kOpusCodec);
2348 SetSendParameters(send_parameters);
2349
2350 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2351 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2352 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2353
2354 constexpr int kMaxBitrateBps = 6000;
2355 rtp_parameters.encodings[0].max_bitrate_bps =
2356 rtc::Optional<int>(kMaxBitrateBps);
2357 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2358
2359 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2360#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2361 constexpr int kMinOverhead = 3333;
2362#else
2363 constexpr int kMinOverhead = 6666;
2364#endif
2365 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2366}
2367
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002369// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002370TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002371 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002372 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002373}
2374
2375TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2376 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002377 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002378 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002379 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002380 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002381 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002382 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002383 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002384
solenberg85a04962015-10-27 03:35:21 -07002385 // Check stats for the added streams.
2386 {
2387 cricket::VoiceMediaInfo info;
2388 EXPECT_EQ(true, channel_->GetStats(&info));
2389
2390 // We have added one send stream. We should see the stats we've set.
2391 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002392 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002393 // We have added one receive stream. We should see empty stats.
2394 EXPECT_EQ(info.receivers.size(), 1u);
2395 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2396 }
solenberg1ac56142015-10-13 03:58:19 -07002397
solenberg566ef242015-11-06 15:34:49 -08002398 // Start sending - this affects some reported stats.
2399 {
2400 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002401 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002402 EXPECT_EQ(true, channel_->GetStats(&info));
2403 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002404 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002405 }
2406
solenberg2100c0b2017-03-01 11:29:29 -08002407 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002408 {
2409 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002410 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002411 EXPECT_EQ(true, channel_->GetStats(&info));
2412 EXPECT_EQ(1u, info.senders.size());
2413 EXPECT_EQ(0u, info.receivers.size());
2414 }
solenberg1ac56142015-10-13 03:58:19 -07002415
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002416 // Deliver a new packet - a default receive stream should be created and we
2417 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002418 {
2419 cricket::VoiceMediaInfo info;
2420 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2421 SetAudioReceiveStreamStats();
2422 EXPECT_EQ(true, channel_->GetStats(&info));
2423 EXPECT_EQ(1u, info.senders.size());
2424 EXPECT_EQ(1u, info.receivers.size());
2425 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002426 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002427 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428}
2429
2430// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002431// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002432TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002433 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002434 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2435 EXPECT_TRUE(AddRecvStream(kSsrcY));
2436 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437}
2438
2439// Test that the local SSRC is the same on sending and receiving channels if the
2440// receive channel is created before the send channel.
2441TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002442 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002443 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002445 cricket::StreamParams::CreateLegacy(kSsrcX)));
2446 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2447 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448}
2449
2450// Test that we can properly receive packets.
2451TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002452 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002453 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002455
2456 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2457 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002458}
2459
2460// Test that we can properly receive packets on multiple streams.
2461TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002462 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002463 const uint32_t ssrc1 = 1;
2464 const uint32_t ssrc2 = 2;
2465 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002466 EXPECT_TRUE(AddRecvStream(ssrc1));
2467 EXPECT_TRUE(AddRecvStream(ssrc2));
2468 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002470 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002471 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002473 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 }
mflodman3d7db262016-04-29 00:57:13 -07002475
2476 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2477 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2478 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2479
2480 EXPECT_EQ(s1.received_packets(), 0);
2481 EXPECT_EQ(s2.received_packets(), 0);
2482 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002483
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002485 EXPECT_EQ(s1.received_packets(), 0);
2486 EXPECT_EQ(s2.received_packets(), 0);
2487 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002488
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002490 EXPECT_EQ(s1.received_packets(), 1);
2491 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2492 EXPECT_EQ(s2.received_packets(), 0);
2493 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002494
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002496 EXPECT_EQ(s1.received_packets(), 1);
2497 EXPECT_EQ(s2.received_packets(), 1);
2498 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2499 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002500
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002502 EXPECT_EQ(s1.received_packets(), 1);
2503 EXPECT_EQ(s2.received_packets(), 1);
2504 EXPECT_EQ(s3.received_packets(), 1);
2505 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002506
mflodman3d7db262016-04-29 00:57:13 -07002507 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2508 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2509 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510}
2511
solenberg2100c0b2017-03-01 11:29:29 -08002512// Test that receiving on an unsignaled stream works (a stream is created).
2513TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002514 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002515 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2516
solenberg7e63ef02015-11-20 00:19:43 -08002517 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002518
2519 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002520 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2521 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002522}
2523
solenberg2100c0b2017-03-01 11:29:29 -08002524// Test that receiving N unsignaled stream works (streams will be created), and
2525// that packets are forwarded to them all.
2526TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002527 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002528 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002529 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2530
solenberg2100c0b2017-03-01 11:29:29 -08002531 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002532 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002533 rtc::SetBE32(&packet[8], ssrc);
2534 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002535
solenberg2100c0b2017-03-01 11:29:29 -08002536 // Verify we have one new stream for each loop iteration.
2537 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002538 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2539 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002540 }
mflodman3d7db262016-04-29 00:57:13 -07002541
solenberg2100c0b2017-03-01 11:29:29 -08002542 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002543 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002544 rtc::SetBE32(&packet[8], ssrc);
2545 DeliverPacket(packet, sizeof(packet));
2546
solenbergebb349d2017-03-13 05:46:15 -07002547 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002548 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2549 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2550 }
2551
2552 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2553 constexpr uint32_t kAnotherSsrc = 667;
2554 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002555 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002556
2557 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002558 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002559 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002560 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002561 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2562 EXPECT_EQ(2, streams[i]->received_packets());
2563 }
2564 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2565 EXPECT_EQ(1, streams[i]->received_packets());
2566 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002567 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002568}
2569
solenberg2100c0b2017-03-01 11:29:29 -08002570// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002571// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002572TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002573 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002574 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002575 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2576
2577 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002578 const uint32_t signaled_ssrc = 1;
2579 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002580 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002581 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002582 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2583 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002584 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002585
2586 // Note that the first unknown SSRC cannot be 0, because we only support
2587 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002588 const uint32_t unsignaled_ssrc = 7011;
2589 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002590 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002591 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2592 packet, sizeof(packet)));
2593 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2594
2595 DeliverPacket(packet, sizeof(packet));
2596 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2597
2598 rtc::SetBE32(&packet[8], signaled_ssrc);
2599 DeliverPacket(packet, sizeof(packet));
2600 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2601 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002602}
2603
solenberg4904fb62017-02-17 12:01:14 -08002604// Two tests to verify that adding a receive stream with the same SSRC as a
2605// previously added unsignaled stream will only recreate underlying stream
2606// objects if the stream parameters have changed.
2607TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2608 EXPECT_TRUE(SetupChannel());
2609
2610 // Spawn unsignaled stream with SSRC=1.
2611 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2612 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2613 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2614 sizeof(kPcmuFrame)));
2615
2616 // Verify that the underlying stream object in Call is not recreated when a
2617 // stream with SSRC=1 is added.
2618 const auto& streams = call_.GetAudioReceiveStreams();
2619 EXPECT_EQ(1, streams.size());
2620 int audio_receive_stream_id = streams.front()->id();
2621 EXPECT_TRUE(AddRecvStream(1));
2622 EXPECT_EQ(1, streams.size());
2623 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2624}
2625
2626TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2627 EXPECT_TRUE(SetupChannel());
2628
2629 // Spawn unsignaled stream with SSRC=1.
2630 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2631 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2632 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2633 sizeof(kPcmuFrame)));
2634
2635 // Verify that the underlying stream object in Call *is* recreated when a
2636 // stream with SSRC=1 is added, and which has changed stream parameters.
2637 const auto& streams = call_.GetAudioReceiveStreams();
2638 EXPECT_EQ(1, streams.size());
2639 int audio_receive_stream_id = streams.front()->id();
2640 cricket::StreamParams stream_params;
2641 stream_params.ssrcs.push_back(1);
2642 stream_params.sync_label = "sync_label";
2643 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2644 EXPECT_EQ(1, streams.size());
2645 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2646}
2647
solenberg0a617e22015-10-20 15:49:38 -07002648// Test that we properly handle failures to add a receive stream.
2649TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002650 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002652 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653}
2654
solenberg0a617e22015-10-20 15:49:38 -07002655// Test that we properly handle failures to add a send stream.
2656TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002657 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002658 voe_.set_fail_create_channel(true);
2659 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2660}
2661
solenberg1ac56142015-10-13 03:58:19 -07002662// Test that AddRecvStream creates new stream.
2663TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002664 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002665 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002666 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002667 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002668}
2669
2670// Test that after adding a recv stream, we do not decode more codecs than
2671// those previously passed into SetRecvCodecs.
2672TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002673 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002674 cricket::AudioRecvParameters parameters;
2675 parameters.codecs.push_back(kIsacCodec);
2676 parameters.codecs.push_back(kPcmuCodec);
2677 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002678 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002679 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2680 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2681 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002682}
2683
2684// Test that we properly clean up any streams that were added, even if
2685// not explicitly removed.
2686TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002687 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002688 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002689 EXPECT_TRUE(AddRecvStream(1));
2690 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002691 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2692 delete channel_;
2693 channel_ = NULL;
2694 EXPECT_EQ(0, voe_.GetNumChannels());
2695}
2696
wu@webrtc.org78187522013-10-07 23:32:02 +00002697TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002698 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002699 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002700}
2701
2702TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002703 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002704 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002705 // Manually delete channel to simulate a failure.
2706 int channel = voe_.GetLastChannel();
2707 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2708 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002709 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002710 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002711 EXPECT_NE(channel, new_channel);
2712 // The last created channel is deleted too.
2713 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002714}
2715
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002716// Test the InsertDtmf on default send stream as caller.
2717TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002718 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719}
2720
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002721// Test the InsertDtmf on default send stream as callee
2722TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002723 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002724}
2725
2726// Test the InsertDtmf on specified send stream as caller.
2727TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002728 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002729}
2730
2731// Test the InsertDtmf on specified send stream as callee.
2732TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002733 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734}
2735
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002736TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002738 EXPECT_CALL(adm_,
2739 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2740 EXPECT_CALL(adm_,
2741 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2742 EXPECT_CALL(adm_,
2743 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002744
solenberg246b8172015-12-08 09:50:23 -08002745 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2746 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747
solenberg246b8172015-12-08 09:50:23 -08002748 // Nothing set in AudioOptions, so everything should be as default.
2749 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002750 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002751 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002752 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2753 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754
2755 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002756 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2757 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002758 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002759 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760
2761 // Turn echo cancellation back on, with settings, and make sure
2762 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002763 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002765 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002766 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002768 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2769 // control.
solenberg76377c52017-02-21 00:54:31 -08002770 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2771 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002772 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002774
2775 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002776 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002778 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2779 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2780 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002781 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002782
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002783 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002784 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2785 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002786 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002787 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002788
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002790 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002794 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002795 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796
2797 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002798 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2799 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2800 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002802 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2803 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002804 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002805
2806 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002807 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2808 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2813 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002814 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2815 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2816 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2817 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002818 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002819 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820
solenberg1ac56142015-10-13 03:58:19 -07002821 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002822 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2823 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2824 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2825 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2828 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830}
2831
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002833 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002834 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002835 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002836 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002837 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002838 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002839 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002840 EXPECT_CALL(adm_,
2841 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2842 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2843 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002844 webrtc::AudioProcessing::Config apm_config;
2845 EXPECT_CALL(*apm_, GetConfig())
2846 .Times(10)
2847 .WillRepeatedly(ReturnPointee(&apm_config));
2848 EXPECT_CALL(*apm_, ApplyConfig(_))
2849 .Times(10)
2850 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002851 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002852
kwiberg686a8ef2016-02-26 03:00:35 -08002853 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
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())));
kwiberg686a8ef2016-02-26 03:00:35 -08002856 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002857 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002858 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859
2860 // Have to add a stream to make SetSend work.
2861 cricket::StreamParams stream1;
2862 stream1.ssrcs.push_back(1);
2863 channel1->AddSendStream(stream1);
2864 cricket::StreamParams stream2;
2865 stream2.ssrcs.push_back(2);
2866 channel2->AddSendStream(stream2);
2867
2868 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002869 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002870 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2871 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2872 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2874 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2875 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2876 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2877 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002878 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002880 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
2883 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002884 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002885 parameters_options_no_ns.options.noise_suppression =
2886 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002892 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002893 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002894 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2895 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2896 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002897 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
2899 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002900 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002901 parameters_options_no_agc.options.auto_gain_control =
2902 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002903 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2904 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2905 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2906 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002908 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002909 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2910 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2911 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002912 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2916 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2918 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002919 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002920
solenberg76377c52017-02-21 00:54:31 -08002921 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2922 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2923 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002926 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927
solenberg76377c52017-02-21 00:54:31 -08002928 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2929 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2930 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2931 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2932 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002933 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002934
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2937 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002938 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002939 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002940 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002941 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002942 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2943 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2944 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2945 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2946 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002947 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002948 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2949 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2950 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002951 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952}
2953
wu@webrtc.orgde305012013-10-31 15:40:38 +00002954// This test verifies DSCP settings are properly applied on voice media channel.
2955TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002956 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002957 cricket::FakeNetworkInterface network_interface;
2958 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002959 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002960
peahb1c9d1d2017-07-25 15:45:24 -07002961 webrtc::AudioProcessing::Config apm_config;
2962 EXPECT_CALL(*apm_, GetConfig())
2963 .Times(3)
2964 .WillRepeatedly(ReturnPointee(&apm_config));
2965 EXPECT_CALL(*apm_, ApplyConfig(_))
2966 .Times(3)
2967 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002968 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002969
solenbergbc37fc82016-04-04 09:54:44 -07002970 channel.reset(
2971 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002972 channel->SetInterface(&network_interface);
2973 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2974 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2975
2976 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002977 channel.reset(
2978 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002979 channel->SetInterface(&network_interface);
2980 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2981
2982 // Verify that setting the option to false resets the
2983 // DiffServCodePoint.
2984 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002985 channel.reset(
2986 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002987 channel->SetInterface(&network_interface);
2988 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2989 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2990
2991 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002992}
2993
solenberg1ac56142015-10-13 03:58:19 -07002994TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002995 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996 cricket::WebRtcVoiceMediaChannel* media_channel =
2997 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002998 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002999 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003000 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003001 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3002 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3003 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003004 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003005 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006}
3007
solenberg1ac56142015-10-13 03:58:19 -07003008TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003009 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003011 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3012 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3013 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003014 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003015 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3017 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003018 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003019 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003020 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003021 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022}
3023
solenberg4bac9c52015-10-09 02:32:53 -07003024TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003025 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003026 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003028 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003030 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3031 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3032 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003033}
3034
solenberg2100c0b2017-03-01 11:29:29 -08003035TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003036 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003037
3038 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003039 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003040 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3041
3042 // Should remember the volume "2" which will be set on new unsignaled streams,
3043 // and also set the gain to 2 on existing unsignaled streams.
3044 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3045 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3046
3047 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3048 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3049 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3050 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3051 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3052 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3053
3054 // Setting gain with SSRC=0 should affect all unsignaled streams.
3055 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003056 if (kMaxUnsignaledRecvStreams > 1) {
3057 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3058 }
solenberg2100c0b2017-03-01 11:29:29 -08003059 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3060
3061 // Setting gain on an individual stream affects only that.
3062 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003063 if (kMaxUnsignaledRecvStreams > 1) {
3064 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3065 }
solenberg2100c0b2017-03-01 11:29:29 -08003066 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003067}
3068
pbos8fc7fa72015-07-15 08:02:58 -07003069TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003070 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003071 const std::string kSyncLabel = "AvSyncLabel";
3072
solenbergff976312016-03-30 23:28:51 -07003073 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003074 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3075 sp.sync_label = kSyncLabel;
3076 // Creating two channels to make sure that sync label is set properly for both
3077 // the default voice channel and following ones.
3078 EXPECT_TRUE(channel_->AddRecvStream(sp));
3079 sp.ssrcs[0] += 1;
3080 EXPECT_TRUE(channel_->AddRecvStream(sp));
3081
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003082 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003083 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003084 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003085 << "SyncGroup should be set based on sync_label";
3086 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003087 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003088 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003089}
3090
solenberg3a941542015-11-16 07:34:50 -08003091// TODO(solenberg): Remove, once recv streams are configured through Call.
3092// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003093TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003094 // Test that setting the header extensions results in the expected state
3095 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003096 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097 ssrcs.push_back(223);
3098 ssrcs.push_back(224);
3099
solenbergff976312016-03-30 23:28:51 -07003100 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003101 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003102 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003103 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003104 cricket::StreamParams::CreateLegacy(ssrc)));
3105 }
3106
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003107 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003108 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003109 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003110 EXPECT_NE(nullptr, s);
3111 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3112 }
3113
3114 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003115 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003116 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003117 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003118 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003119 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003120 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003121 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003122 EXPECT_NE(nullptr, s);
3123 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003124 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3125 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003126 for (const auto& s_ext : s_exts) {
3127 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003128 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003129 }
3130 }
3131 }
3132 }
3133
3134 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003135 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003136 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003137 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003138 EXPECT_NE(nullptr, s);
3139 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3140 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003141}
3142
3143TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3144 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003145 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003146 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003147 static const unsigned char kRtcp[] = {
3148 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3149 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3152 };
jbaucheec21bd2016-03-20 06:15:43 -07003153 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003154
solenbergff976312016-03-30 23:28:51 -07003155 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003156 cricket::WebRtcVoiceMediaChannel* media_channel =
3157 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003158 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003159 EXPECT_TRUE(media_channel->AddRecvStream(
3160 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3161
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003162 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003163 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003164 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003165 EXPECT_EQ(0, s->received_packets());
3166 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3167 EXPECT_EQ(1, s->received_packets());
3168 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3169 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003170}
Minyue2013aec2015-05-13 14:14:42 +02003171
solenberg0a617e22015-10-20 15:49:38 -07003172// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003173// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003174TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003175 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003176 EXPECT_TRUE(AddRecvStream(kSsrcY));
3177 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003178 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003179 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3180 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3181 EXPECT_TRUE(AddRecvStream(kSsrcW));
3182 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003183}
3184
solenberg7602aab2016-11-14 11:30:07 -08003185TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3186 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003187 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003188 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003189 cricket::StreamParams::CreateLegacy(kSsrcY)));
3190 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3191 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3192 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003193 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003194 cricket::StreamParams::CreateLegacy(kSsrcW)));
3195 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3196 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003197}
stefan658910c2015-09-03 05:48:32 -07003198
deadbeef884f5852016-01-15 09:20:04 -08003199TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003200 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003201 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3202 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003203
3204 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003205 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3206 EXPECT_TRUE(AddRecvStream(kSsrcX));
3207 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003208
3209 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003210 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3211 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003212
3213 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003214 channel_->SetRawAudioSink(kSsrcX, nullptr);
3215 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003216}
3217
solenberg2100c0b2017-03-01 11:29:29 -08003218TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003219 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003220 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3221 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003222 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3223 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003224
3225 // Should be able to set a default sink even when no stream exists.
3226 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3227
solenberg2100c0b2017-03-01 11:29:29 -08003228 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3229 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003230 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003232
3233 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003234 channel_->SetRawAudioSink(kSsrc0, nullptr);
3235 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003236
3237 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003238 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3239 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003240
3241 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003242 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003243 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003244 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3245
3246 // Spawn another unsignaled stream - it should be assigned the default sink
3247 // and the previous unsignaled stream should lose it.
3248 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3249 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3250 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3251 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003252 if (kMaxUnsignaledRecvStreams > 1) {
3253 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3254 }
solenberg2100c0b2017-03-01 11:29:29 -08003255 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3256
3257 // Reset the default sink - the second unsignaled stream should lose it.
3258 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003259 if (kMaxUnsignaledRecvStreams > 1) {
3260 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3261 }
solenberg2100c0b2017-03-01 11:29:29 -08003262 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3263
3264 // Try setting the default sink while two streams exists.
3265 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003266 if (kMaxUnsignaledRecvStreams > 1) {
3267 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3268 }
solenberg2100c0b2017-03-01 11:29:29 -08003269 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3270
3271 // Try setting the sink for the first unsignaled stream using its known SSRC.
3272 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003273 if (kMaxUnsignaledRecvStreams > 1) {
3274 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3275 }
solenberg2100c0b2017-03-01 11:29:29 -08003276 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003277 if (kMaxUnsignaledRecvStreams > 1) {
3278 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3279 }
deadbeef884f5852016-01-15 09:20:04 -08003280}
3281
skvlad7a43d252016-03-22 15:32:27 -07003282// Test that, just like the video channel, the voice channel communicates the
3283// network state to the call.
3284TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003285 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003286
3287 EXPECT_EQ(webrtc::kNetworkUp,
3288 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3289 EXPECT_EQ(webrtc::kNetworkUp,
3290 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3291
3292 channel_->OnReadyToSend(false);
3293 EXPECT_EQ(webrtc::kNetworkDown,
3294 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3295 EXPECT_EQ(webrtc::kNetworkUp,
3296 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3297
3298 channel_->OnReadyToSend(true);
3299 EXPECT_EQ(webrtc::kNetworkUp,
3300 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3301 EXPECT_EQ(webrtc::kNetworkUp,
3302 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3303}
3304
aleloi18e0b672016-10-04 02:45:47 -07003305// Test that playout is still started after changing parameters
3306TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3307 SetupRecvStream();
3308 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003309 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003310
3311 // Changing RTP header extensions will recreate the AudioReceiveStream.
3312 cricket::AudioRecvParameters parameters;
3313 parameters.extensions.push_back(
3314 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3315 channel_->SetRecvParameters(parameters);
3316
solenberg2100c0b2017-03-01 11:29:29 -08003317 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003318}
3319
stefan658910c2015-09-03 05:48:32 -07003320// Tests that the library initializes and shuts down properly.
3321TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003322 // If the VoiceEngine wants to gather available codecs early, that's fine but
3323 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003324 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3325 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003326 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003327 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003328 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003329 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003330 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003331 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003332 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003333 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3334 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003335 EXPECT_TRUE(channel != nullptr);
3336 delete channel;
solenbergff976312016-03-30 23:28:51 -07003337}
stefan658910c2015-09-03 05:48:32 -07003338
solenbergff976312016-03-30 23:28:51 -07003339// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003340TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3341 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3342 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3343 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003344 // Return 100ms just in case this function gets called. If we don't,
3345 // we could enter a tight loop since the mock would return 0.
3346 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003347 {
peaha9cc40b2017-06-29 08:32:09 -07003348 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3349 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003350 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003351 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003352 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003353 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003354 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003355 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003356 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003357 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3358 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3359 EXPECT_TRUE(channel != nullptr);
3360 delete channel;
3361 }
stefan658910c2015-09-03 05:48:32 -07003362}
3363
ossu20a4b3f2017-04-27 02:08:52 -07003364// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3365TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003366 // TODO(ossu): Why are the payload types of codecs with non-static payload
3367 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003368 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3369 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003370 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003371 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003372 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003373 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003374 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003375 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3376 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3377 (clockrate == 0 || codec.clockrate == clockrate);
3378 };
3379 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003380 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003381 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003382 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003383 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003384 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003385 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003386 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003387 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003388 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003389 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003390 EXPECT_EQ(126, codec.id);
3391 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3392 // Remove these checks once both send and receive side assigns payload types
3393 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003394 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003395 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003396 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003397 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003398 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003399 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003400 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003401 EXPECT_EQ(111, codec.id);
3402 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3403 EXPECT_EQ("10", codec.params.find("minptime")->second);
3404 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3405 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003406 }
3407 }
stefan658910c2015-09-03 05:48:32 -07003408}
3409
3410// Tests that VoE supports at least 32 channels
3411TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003412 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3413 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003414 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003415 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003416 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003417 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003418 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003419 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003420 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003421
3422 cricket::VoiceMediaChannel* channels[32];
3423 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003424 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003425 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3426 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003427 if (!channel)
3428 break;
stefan658910c2015-09-03 05:48:32 -07003429 channels[num_channels++] = channel;
3430 }
3431
tfarina5237aaf2015-11-10 23:44:30 -08003432 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003433 EXPECT_EQ(expected, num_channels);
3434
3435 while (num_channels > 0) {
3436 delete channels[--num_channels];
3437 }
stefan658910c2015-09-03 05:48:32 -07003438}
3439
3440// Test that we set our preferred codecs properly.
3441TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003442 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3443 // - Check that our builtin codecs are usable by Channel.
3444 // - The codecs provided by the engine is usable by Channel.
3445 // It does not check that the codecs in the RecvParameters are actually
3446 // what we sent in - though it's probably reasonable to expect so, if
3447 // SetRecvParameters returns true.
3448 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003449 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3450 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003451 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003452 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003453 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003454 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003455 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003456 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003457 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003458 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3459 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003460 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003461 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003462 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003463}
ossu9def8002017-02-09 05:14:32 -08003464
3465TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3466 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003467 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3468 {48000, 2, 16000, 10000, 20000}};
3469 spec1.info.allow_comfort_noise = false;
3470 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003471 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003472 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3473 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003474 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003475 specs.push_back(webrtc::AudioCodecSpec{
3476 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3477 {16000, 1, 13300}});
3478 specs.push_back(
3479 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3480 specs.push_back(
3481 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003482
ossueb1fde42017-05-02 06:46:30 -07003483 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3484 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3485 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003486 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003487 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003488 .WillOnce(Return(specs));
3489
peaha9cc40b2017-06-29 08:32:09 -07003490 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3491 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003492 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003493 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003494 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003495 auto codecs = engine.recv_codecs();
3496 EXPECT_EQ(11, codecs.size());
3497
3498 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3499 // check the actual values safely, to provide better test results.
3500 auto get_codec =
3501 [&codecs](size_t index) -> const cricket::AudioCodec& {
3502 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3503 if (codecs.size() > index)
3504 return codecs[index];
3505 return missing_codec;
3506 };
3507
3508 // Ensure the general codecs are generated first and in order.
3509 for (size_t i = 0; i != specs.size(); ++i) {
3510 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3511 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3512 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3513 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3514 }
3515
3516 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003517 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003518 auto find_codec =
3519 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3520 for (size_t i = 0; i != codecs.size(); ++i) {
3521 const cricket::AudioCodec& codec = codecs[i];
3522 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3523 codec.clockrate == format.clockrate_hz &&
3524 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003525 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003526 }
3527 }
3528 return -1;
3529 };
3530
3531 // Ensure all supplementary codecs are generated last. Their internal ordering
3532 // is not important.
3533 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3534 const int num_specs = static_cast<int>(specs.size());
3535 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3536 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3537 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3538 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3539 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3540 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3541 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3542}