blob: c8a452a99b03d6e314add714947ba381c0432b55 [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);
Niels Möller6f72f562017-10-19 13:15:17 +020087 EXPECT_CALL(*adm, AddRef()).Times(1);
88 EXPECT_CALL(*adm, Release())
89 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -070090#if !defined(WEBRTC_IOS)
91 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
92 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
93 ChannelType::kChannelBoth)).WillOnce(Return(0));
94#if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, SetRecordingDevice(
96 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
97 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
98 .WillOnce(Return(0));
99#else
100 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
101#endif // #if defined(WEBRTC_WIN)
102 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
103 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
104 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
105 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
106#if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, SetPlayoutDevice(
108 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
109 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
110 .WillOnce(Return(0));
111#else
112 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
113#endif // #if defined(WEBRTC_WIN)
114 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
115 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
116 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
117#endif // #if !defined(WEBRTC_IOS)
118 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
119 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
122}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200123} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124
solenbergff976312016-03-30 23:28:51 -0700125// Tests that our stub library "works".
126TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700127 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700128 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700129 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
130 new rtc::RefCountedObject<
131 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700132 webrtc::AudioProcessing::Config apm_config;
133 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
134 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700135 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
136 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
137 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800138 StrictMock<MockTransmitMixer> transmit_mixer;
139 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700140 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700141 EXPECT_FALSE(voe.IsInited());
142 {
ossuc54071d2016-08-17 02:45:41 -0700143 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700144 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700145 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700146 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700147 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700148 EXPECT_TRUE(voe.IsInited());
149 }
150 EXPECT_FALSE(voe.IsInited());
151}
152
deadbeef884f5852016-01-15 09:20:04 -0800153class FakeAudioSink : public webrtc::AudioSinkInterface {
154 public:
155 void OnData(const Data& audio) override {}
156};
157
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800158class FakeAudioSource : public cricket::AudioSource {
159 void SetSink(Sink* sink) override {}
160};
161
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162class WebRtcVoiceEngineTestFake : public testing::Test {
163 public:
stefanba4c0e42016-02-04 04:12:24 -0800164 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
165
166 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700167 : apm_(new rtc::RefCountedObject<
168 StrictMock<webrtc::test::MockAudioProcessing>>()),
169 apm_gc_(*apm_->gain_control()),
170 apm_ec_(*apm_->echo_cancellation()),
171 apm_ns_(*apm_->noise_suppression()),
172 apm_vd_(*apm_->voice_detection()),
173 call_(webrtc::Call::Config(&event_log_)),
174 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700175 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800176 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700177 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800178 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700179 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
180 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
182 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
183 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800184 // Default Options.
185 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
186 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
187 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
190 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
191 // Init does not overwrite default AGC config.
192 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
193 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
194 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
195 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
196 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
197 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700198 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800199 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700200 // factories. Those tests should probably be moved elsewhere.
201 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
202 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
203 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700204 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700205 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700206 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200207 send_parameters_.codecs.push_back(kPcmuCodec);
208 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800209 // Default Options.
210 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 }
solenberg8189b022016-06-14 12:13:00 -0700212
solenbergff976312016-03-30 23:28:51 -0700213 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700214 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700215 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
216 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200217 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000218 }
solenberg8189b022016-06-14 12:13:00 -0700219
solenbergff976312016-03-30 23:28:51 -0700220 bool SetupRecvStream() {
221 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700222 return false;
223 }
solenberg2100c0b2017-03-01 11:29:29 -0800224 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700225 }
solenberg8189b022016-06-14 12:13:00 -0700226
solenbergff976312016-03-30 23:28:51 -0700227 bool SetupSendStream() {
228 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000229 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 }
solenberg2100c0b2017-03-01 11:29:29 -0800231 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800232 return false;
233 }
peaha9cc40b2017-06-29 08:32:09 -0700234 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800235 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
solenberg8189b022016-06-14 12:13:00 -0700237
238 bool AddRecvStream(uint32_t ssrc) {
239 EXPECT_TRUE(channel_);
240 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
241 }
242
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000243 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700244 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700245 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800246 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
247 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700248 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800249 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000250 }
solenberg8189b022016-06-14 12:13:00 -0700251
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700253 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000254 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 }
solenberg8189b022016-06-14 12:13:00 -0700256
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200257 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 }
260
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100261 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
262 const auto* send_stream = call_.GetAudioSendStream(ssrc);
263 EXPECT_TRUE(send_stream);
264 return *send_stream;
265 }
266
deadbeef884f5852016-01-15 09:20:04 -0800267 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
268 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
269 EXPECT_TRUE(recv_stream);
270 return *recv_stream;
271 }
272
solenberg3a941542015-11-16 07:34:50 -0800273 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800274 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800275 }
276
solenberg7add0582015-11-20 09:59:34 -0800277 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800278 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800279 }
280
solenberg059fb442016-10-26 05:12:24 -0700281 void SetSend(bool enable) {
282 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700283 if (enable) {
284 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
285 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700287 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700288 }
solenberg059fb442016-10-26 05:12:24 -0700289 channel_->SetSend(enable);
290 }
291
292 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700293 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700294 ASSERT_TRUE(channel_);
295 EXPECT_TRUE(channel_->SetSendParameters(params));
296 }
297
minyue6b825df2016-10-31 04:08:32 -0700298 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
299 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700300 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700301 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700302 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700303 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700304 }
305 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700306 }
307
solenbergffbbcac2016-11-17 05:25:37 -0800308 void TestInsertDtmf(uint32_t ssrc, bool caller,
309 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700310 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000311 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700312 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313 // send stream.
314 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800315 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700319 SetSendParameters(send_parameters_);
320 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800322 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800323 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700324 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326
327 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700328 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800329 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800331 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000332 }
333
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800335 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100337 // Test send.
338 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800339 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100340 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800341 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800342 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800343 EXPECT_EQ(codec.id, telephone_event.payload_type);
344 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100345 EXPECT_EQ(2, telephone_event.event_code);
346 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 }
348
349 // Test that send bandwidth is set correctly.
350 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000351 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
352 // |expected_result| is the expected result from SetMaxSendBandwidth().
353 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700354 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
355 int max_bitrate,
356 bool expected_result,
357 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200358 cricket::AudioSendParameters parameters;
359 parameters.codecs.push_back(codec);
360 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700361 if (expected_result) {
362 SetSendParameters(parameters);
363 } else {
364 EXPECT_FALSE(channel_->SetSendParameters(parameters));
365 }
solenberg2100c0b2017-03-01 11:29:29 -0800366 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 }
368
skvlade0d46372016-04-07 22:59:22 -0700369 // Sets the per-stream maximum bitrate limit for the specified SSRC.
370 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700371 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700372 EXPECT_EQ(1UL, parameters.encodings.size());
373
deadbeefe702b302017-02-04 12:09:01 -0800374 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700375 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700376 }
377
solenberg059fb442016-10-26 05:12:24 -0700378 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700379 cricket::AudioSendParameters send_parameters;
380 send_parameters.codecs.push_back(codec);
381 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700382 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700383 }
384
ossu20a4b3f2017-04-27 02:08:52 -0700385 void CheckSendCodecBitrate(int32_t ssrc,
386 const char expected_name[],
387 int expected_bitrate) {
388 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
389 EXPECT_EQ(expected_name, spec->format.name);
390 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700391 }
392
ossu20a4b3f2017-04-27 02:08:52 -0700393 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
394 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700395 }
396
minyue6b825df2016-10-31 04:08:32 -0700397 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
398 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
399 }
400
skvlade0d46372016-04-07 22:59:22 -0700401 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
402 int global_max,
403 int stream_max,
404 bool expected_result,
405 int expected_codec_bitrate) {
406 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800407 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700408
409 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700410 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800411 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700412
413 // Verify that reading back the parameters gives results
414 // consistent with the Set() result.
415 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800416 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700417 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
418 EXPECT_EQ(expected_result ? stream_max : -1,
419 resulting_parameters.encodings[0].max_bitrate_bps);
420
421 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800422 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700423 }
424
stefan13f1a0a2016-11-30 07:22:58 -0800425 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
426 int expected_min_bitrate_bps,
427 const char* start_bitrate_kbps,
428 int expected_start_bitrate_bps,
429 const char* max_bitrate_kbps,
430 int expected_max_bitrate_bps) {
431 EXPECT_TRUE(SetupSendStream());
432 auto& codecs = send_parameters_.codecs;
433 codecs.clear();
434 codecs.push_back(kOpusCodec);
435 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
436 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
437 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
438 SetSendParameters(send_parameters_);
439
440 EXPECT_EQ(expected_min_bitrate_bps,
441 call_.GetConfig().bitrate_config.min_bitrate_bps);
442 EXPECT_EQ(expected_start_bitrate_bps,
443 call_.GetConfig().bitrate_config.start_bitrate_bps);
444 EXPECT_EQ(expected_max_bitrate_bps,
445 call_.GetConfig().bitrate_config.max_bitrate_bps);
446 }
447
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000448 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700449 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000450
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000451 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800452 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000453
454 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700455 send_parameters_.extensions.push_back(
456 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700457 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800458 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000459
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000460 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200461 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700462 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800463 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000464
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000465 // Ensure extension is set properly.
466 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700467 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700468 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800469 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
470 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
471 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000472
solenberg7add0582015-11-20 09:59:34 -0800473 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000474 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800475 cricket::StreamParams::CreateLegacy(kSsrcY)));
476 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
477 call_.GetAudioSendStream(kSsrcY));
478 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
479 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
480 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000481
482 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200483 send_parameters_.codecs.push_back(kPcmuCodec);
484 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700485 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
487 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000488 }
489
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000490 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700491 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000495
496 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700497 recv_parameters_.extensions.push_back(
498 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800499 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800500 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000501
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000502 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800503 recv_parameters_.extensions.clear();
504 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800505 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000506
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000507 // Ensure extension is set properly.
508 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700509 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800510 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
512 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
513 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000514
solenberg7add0582015-11-20 09:59:34 -0800515 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800516 EXPECT_TRUE(AddRecvStream(kSsrcY));
517 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
518 call_.GetAudioReceiveStream(kSsrcY));
519 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
520 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
521 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000522
523 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800524 recv_parameters_.extensions.clear();
525 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
527 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000528 }
529
solenberg85a04962015-10-27 03:35:21 -0700530 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
531 webrtc::AudioSendStream::Stats stats;
532 stats.local_ssrc = 12;
533 stats.bytes_sent = 345;
534 stats.packets_sent = 678;
535 stats.packets_lost = 9012;
536 stats.fraction_lost = 34.56f;
537 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800538 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700539 stats.ext_seqnum = 789;
540 stats.jitter_ms = 12;
541 stats.rtt_ms = 345;
542 stats.audio_level = 678;
543 stats.aec_quality_min = 9.01f;
544 stats.echo_delay_median_ms = 234;
545 stats.echo_delay_std_ms = 567;
546 stats.echo_return_loss = 890;
547 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700548 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800549 stats.residual_echo_likelihood_recent_max = 0.6f;
ivoce1198e02017-09-08 08:13:19 -0700550 stats.ana_statistics.bitrate_action_counter = rtc::Optional<uint32_t>(321);
551 stats.ana_statistics.channel_action_counter = rtc::Optional<uint32_t>(432);
552 stats.ana_statistics.dtx_action_counter = rtc::Optional<uint32_t>(543);
553 stats.ana_statistics.fec_action_counter = rtc::Optional<uint32_t>(654);
ivoc0d0b9122017-09-08 13:24:21 -0700554 stats.ana_statistics.frame_length_increase_counter =
ivoce1198e02017-09-08 08:13:19 -0700555 rtc::Optional<uint32_t>(765);
ivoc0d0b9122017-09-08 13:24:21 -0700556 stats.ana_statistics.frame_length_decrease_counter =
557 rtc::Optional<uint32_t>(876);
558 stats.ana_statistics.uplink_packet_loss_fraction =
559 rtc::Optional<float>(987.0);
solenberg85a04962015-10-27 03:35:21 -0700560 stats.typing_noise_detected = true;
561 return stats;
562 }
563 void SetAudioSendStreamStats() {
564 for (auto* s : call_.GetAudioSendStreams()) {
565 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200566 }
solenberg85a04962015-10-27 03:35:21 -0700567 }
solenberg566ef242015-11-06 15:34:49 -0800568 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
569 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700570 const auto stats = GetAudioSendStreamStats();
571 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
572 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
573 EXPECT_EQ(info.packets_sent, stats.packets_sent);
574 EXPECT_EQ(info.packets_lost, stats.packets_lost);
575 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
576 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800577 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700578 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
579 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
580 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
581 EXPECT_EQ(info.audio_level, stats.audio_level);
582 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
583 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
584 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
585 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
586 EXPECT_EQ(info.echo_return_loss_enhancement,
587 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700588 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800589 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
590 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700591 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
592 stats.ana_statistics.bitrate_action_counter);
593 EXPECT_EQ(info.ana_statistics.channel_action_counter,
594 stats.ana_statistics.channel_action_counter);
595 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
596 stats.ana_statistics.dtx_action_counter);
597 EXPECT_EQ(info.ana_statistics.fec_action_counter,
598 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700599 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
600 stats.ana_statistics.frame_length_increase_counter);
601 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
602 stats.ana_statistics.frame_length_decrease_counter);
603 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
604 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800605 EXPECT_EQ(info.typing_noise_detected,
606 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700607 }
608
609 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
610 webrtc::AudioReceiveStream::Stats stats;
611 stats.remote_ssrc = 123;
612 stats.bytes_rcvd = 456;
613 stats.packets_rcvd = 768;
614 stats.packets_lost = 101;
615 stats.fraction_lost = 23.45f;
616 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800617 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700618 stats.ext_seqnum = 678;
619 stats.jitter_ms = 901;
620 stats.jitter_buffer_ms = 234;
621 stats.jitter_buffer_preferred_ms = 567;
622 stats.delay_estimate_ms = 890;
623 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700624 stats.total_samples_received = 5678901;
625 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200626 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200627 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700628 stats.expand_rate = 5.67f;
629 stats.speech_expand_rate = 8.90f;
630 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200631 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700632 stats.accelerate_rate = 4.56f;
633 stats.preemptive_expand_rate = 7.89f;
634 stats.decoding_calls_to_silence_generator = 12;
635 stats.decoding_calls_to_neteq = 345;
636 stats.decoding_normal = 67890;
637 stats.decoding_plc = 1234;
638 stats.decoding_cng = 5678;
639 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700640 stats.decoding_muted_output = 3456;
641 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200642 return stats;
643 }
644 void SetAudioReceiveStreamStats() {
645 for (auto* s : call_.GetAudioReceiveStreams()) {
646 s->SetStats(GetAudioReceiveStreamStats());
647 }
648 }
649 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700650 const auto stats = GetAudioReceiveStreamStats();
651 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
652 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
653 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
654 EXPECT_EQ(info.packets_lost, stats.packets_lost);
655 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
656 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800657 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700658 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
659 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
660 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200661 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700662 stats.jitter_buffer_preferred_ms);
663 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
664 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700665 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
666 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200667 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200668 EXPECT_EQ(info.jitter_buffer_delay_seconds,
669 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700670 EXPECT_EQ(info.expand_rate, stats.expand_rate);
671 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
672 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200673 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700674 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
675 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200676 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700677 stats.decoding_calls_to_silence_generator);
678 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
679 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
680 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
681 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
682 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700683 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700684 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200685 }
hbos1acfbd22016-11-17 23:43:29 -0800686 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
687 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
688 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
689 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
690 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
691 codec.ToCodecParameters());
692 }
693 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
694 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
695 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
696 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
697 codec.ToCodecParameters());
698 }
699 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200700
peah8271d042016-11-22 07:24:52 -0800701 bool IsHighPassFilterEnabled() {
702 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
703 }
704
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700706 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700707 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800708 webrtc::test::MockGainControl& apm_gc_;
709 webrtc::test::MockEchoCancellation& apm_ec_;
710 webrtc::test::MockNoiseSuppression& apm_ns_;
711 webrtc::test::MockVoiceDetection& apm_vd_;
712 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700713 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200714 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700716 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700717 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200718 cricket::AudioSendParameters send_parameters_;
719 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800720 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700721 webrtc::AudioProcessing::Config apm_config_;
722
stefanba4c0e42016-02-04 04:12:24 -0800723 private:
724 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725};
726
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727// Tests that we can create and destroy a channel.
728TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700729 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730}
731
solenberg31fec402016-05-06 02:13:12 -0700732// Test that we can add a send stream and that it has the correct defaults.
733TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
734 EXPECT_TRUE(SetupChannel());
735 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800736 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
737 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
738 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700739 EXPECT_EQ("", config.rtp.c_name);
740 EXPECT_EQ(0u, config.rtp.extensions.size());
741 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
742 config.send_transport);
743}
744
745// Test that we can add a receive stream and that it has the correct defaults.
746TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
747 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800748 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700749 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800750 GetRecvStreamConfig(kSsrcX);
751 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700752 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
753 EXPECT_FALSE(config.rtp.transport_cc);
754 EXPECT_EQ(0u, config.rtp.extensions.size());
755 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
756 config.rtcp_send_transport);
757 EXPECT_EQ("", config.sync_group);
758}
759
stefanba4c0e42016-02-04 04:12:24 -0800760TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700761 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800762 bool opus_found = false;
763 for (cricket::AudioCodec codec : codecs) {
764 if (codec.name == "opus") {
765 EXPECT_TRUE(HasTransportCc(codec));
766 opus_found = true;
767 }
768 }
769 EXPECT_TRUE(opus_found);
770}
771
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772// Test that we set our inbound codecs properly, including changing PT.
773TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700774 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioRecvParameters parameters;
776 parameters.codecs.push_back(kIsacCodec);
777 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800778 parameters.codecs.push_back(kTelephoneEventCodec1);
779 parameters.codecs.push_back(kTelephoneEventCodec2);
780 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200781 parameters.codecs[2].id = 126;
782 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800783 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700784 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
785 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
786 {{0, {"PCMU", 8000, 1}},
787 {106, {"ISAC", 16000, 1}},
788 {126, {"telephone-event", 8000, 1}},
789 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
792// Test that we fail to set an unknown inbound codec.
793TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700794 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 cricket::AudioRecvParameters parameters;
796 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700797 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799}
800
801// Test that we fail if we have duplicate types in the inbound list.
802TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700803 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200804 cricket::AudioRecvParameters parameters;
805 parameters.codecs.push_back(kIsacCodec);
806 parameters.codecs.push_back(kCn16000Codec);
807 parameters.codecs[1].id = kIsacCodec.id;
808 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that we can decode OPUS without stereo parameters.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kPcmuCodec);
817 parameters.codecs.push_back(kOpusCodec);
818 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800819 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700820 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
821 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
822 {{0, {"PCMU", 8000, 1}},
823 {103, {"ISAC", 16000, 1}},
824 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825}
826
827// Test that we can decode OPUS with stereo = 0.
828TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700829 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 cricket::AudioRecvParameters parameters;
831 parameters.codecs.push_back(kIsacCodec);
832 parameters.codecs.push_back(kPcmuCodec);
833 parameters.codecs.push_back(kOpusCodec);
834 parameters.codecs[2].params["stereo"] = "0";
835 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800836 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700837 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
838 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
839 {{0, {"PCMU", 8000, 1}},
840 {103, {"ISAC", 16000, 1}},
841 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842}
843
844// Test that we can decode OPUS with stereo = 1.
845TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700846 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200847 cricket::AudioRecvParameters parameters;
848 parameters.codecs.push_back(kIsacCodec);
849 parameters.codecs.push_back(kPcmuCodec);
850 parameters.codecs.push_back(kOpusCodec);
851 parameters.codecs[2].params["stereo"] = "1";
852 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800853 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700854 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
855 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
856 {{0, {"PCMU", 8000, 1}},
857 {103, {"ISAC", 16000, 1}},
858 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859}
860
861// Test that changes to recv codecs are applied to all streams.
862TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700863 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 cricket::AudioRecvParameters parameters;
865 parameters.codecs.push_back(kIsacCodec);
866 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800867 parameters.codecs.push_back(kTelephoneEventCodec1);
868 parameters.codecs.push_back(kTelephoneEventCodec2);
869 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200870 parameters.codecs[2].id = 126;
871 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700872 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
873 EXPECT_TRUE(AddRecvStream(ssrc));
874 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
875 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
876 {{0, {"PCMU", 8000, 1}},
877 {106, {"ISAC", 16000, 1}},
878 {126, {"telephone-event", 8000, 1}},
879 {107, {"telephone-event", 32000, 1}}})));
880 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881}
882
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800887 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889
solenberg2100c0b2017-03-01 11:29:29 -0800890 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800891 ASSERT_EQ(1, dm.count(106));
892 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893}
894
895// Test that we can apply the same set of codecs again while playing.
896TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700897 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 cricket::AudioRecvParameters parameters;
899 parameters.codecs.push_back(kIsacCodec);
900 parameters.codecs.push_back(kCn16000Codec);
901 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700902 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
deadbeefcb383672017-04-26 16:28:42 -0700905 // Remapping a payload type to a different codec should fail.
906 parameters.codecs[0] = kOpusCodec;
907 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800909 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910}
911
912// Test that we can add a codec while playing.
913TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700914 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 cricket::AudioRecvParameters parameters;
916 parameters.codecs.push_back(kIsacCodec);
917 parameters.codecs.push_back(kCn16000Codec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700919 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 parameters.codecs.push_back(kOpusCodec);
922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
deadbeefcb383672017-04-26 16:28:42 -0700926// Test that we accept adding the same codec with a different payload type.
927// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
928TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
929 EXPECT_TRUE(SetupRecvStream());
930 cricket::AudioRecvParameters parameters;
931 parameters.codecs.push_back(kIsacCodec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
933
934 ++parameters.codecs[0].id;
935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
936}
937
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000941 // Test that when autobw is enabled, bitrate is kept as the default
942 // value. autobw is enabled for the following tests because the target
943 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
945 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700946 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947
948 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700949 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950
ossu20a4b3f2017-04-27 02:08:52 -0700951 // opus, default bitrate == 32000 in mono.
952 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953}
954
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
960 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700961 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
965 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
966 // Rates above the max (510000) should be capped.
967 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000970TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000972
973 // Test that we can only set a maximum bitrate for a fixed-rate codec
974 // if it's bigger than the fixed rate.
975
976 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700977 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
983 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984}
985
986TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700987 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200988 const int kDesiredBitrate = 128000;
989 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700990 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200991 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700992 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000993
994 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800995 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000996
solenberg2100c0b2017-03-01 11:29:29 -0800997 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000998}
999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000// Test that bitrate cannot be set for CBR codecs.
1001// Bitrate is ignored if it is higher than the fixed bitrate.
1002// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001003TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001004 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005
1006 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009
1010 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001011 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001013
1014 send_parameters_.max_bandwidth_bps = 128;
1015 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001016 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017}
1018
skvlade0d46372016-04-07 22:59:22 -07001019// Test that the per-stream bitrate limit and the global
1020// bitrate limit both apply.
1021TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1022 EXPECT_TRUE(SetupSendStream());
1023
ossu20a4b3f2017-04-27 02:08:52 -07001024 // opus, default bitrate == 32000.
1025 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1028 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1029
1030 // CBR codecs allow both maximums to exceed the bitrate.
1031 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1035
1036 // CBR codecs don't allow per stream maximums to be too low.
1037 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1038 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1039}
1040
1041// Test that an attempt to set RtpParameters for a stream that does not exist
1042// fails.
1043TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1044 EXPECT_TRUE(SetupChannel());
1045 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001046 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001047 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1048
1049 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001050 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001051}
1052
1053TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001054 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001055 // This test verifies that setting RtpParameters succeeds only if
1056 // the structure contains exactly one encoding.
1057 // TODO(skvlad): Update this test when we start supporting setting parameters
1058 // for each encoding individually.
1059
1060 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001061 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001062 // Two or more encodings should result in failure.
1063 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001065 // Zero encodings should also fail.
1066 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001067 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001068}
1069
1070// Changing the SSRC through RtpParameters is not allowed.
1071TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1072 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001074 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001076}
1077
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001078// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001079// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1081 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001082 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001084 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001085 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086 ASSERT_EQ(1u, parameters.encodings.size());
1087 ASSERT_TRUE(parameters.encodings[0].active);
1088 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001089 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1090 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091
1092 // Now change it back to active and verify we resume sending.
1093 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001094 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1095 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001096}
1097
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001098// Test that SetRtpSendParameters configures the correct encoding channel for
1099// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001100TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1101 SetupForMultiSendStream();
1102 // Create send streams.
1103 for (uint32_t ssrc : kSsrcs4) {
1104 EXPECT_TRUE(
1105 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1106 }
1107 // Configure one stream to be limited by the stream config, another to be
1108 // limited by the global max, and the third one with no per-stream limit
1109 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001110 SetGlobalMaxBitrate(kOpusCodec, 32000);
1111 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1112 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001113 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1114
ossu20a4b3f2017-04-27 02:08:52 -07001115 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1116 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1117 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001118
1119 // Remove the global cap; the streams should switch to their respective
1120 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001121 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001122 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1123 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1124 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001125}
1126
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127// Test that GetRtpSendParameters returns the currently configured codecs.
1128TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129 EXPECT_TRUE(SetupSendStream());
1130 cricket::AudioSendParameters parameters;
1131 parameters.codecs.push_back(kIsacCodec);
1132 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001133 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001134
solenberg2100c0b2017-03-01 11:29:29 -08001135 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001136 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001137 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1138 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001139}
1140
deadbeefcb443432016-12-12 11:12:36 -08001141// Test that GetRtpSendParameters returns an SSRC.
1142TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1143 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001144 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001145 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001146 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001147}
1148
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151 EXPECT_TRUE(SetupSendStream());
1152 cricket::AudioSendParameters parameters;
1153 parameters.codecs.push_back(kIsacCodec);
1154 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001155 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156
solenberg2100c0b2017-03-01 11:29:29 -08001157 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001158
1159 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001160 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001161
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001162 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001163 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1164 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001165}
1166
minyuececec102017-03-27 13:04:25 -07001167// Test that max_bitrate_bps in send stream config gets updated correctly when
1168// SetRtpSendParameters is called.
1169TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1170 webrtc::test::ScopedFieldTrials override_field_trials(
1171 "WebRTC-Audio-SendSideBwe/Enabled/");
1172 EXPECT_TRUE(SetupSendStream());
1173 cricket::AudioSendParameters send_parameters;
1174 send_parameters.codecs.push_back(kOpusCodec);
1175 SetSendParameters(send_parameters);
1176
1177 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1178 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1179 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1180
1181 constexpr int kMaxBitrateBps = 6000;
1182 rtp_parameters.encodings[0].max_bitrate_bps =
1183 rtc::Optional<int>(kMaxBitrateBps);
1184 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1185
1186 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1187 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1188}
1189
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001190// Test that GetRtpReceiveParameters returns the currently configured codecs.
1191TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1192 EXPECT_TRUE(SetupRecvStream());
1193 cricket::AudioRecvParameters parameters;
1194 parameters.codecs.push_back(kIsacCodec);
1195 parameters.codecs.push_back(kPcmuCodec);
1196 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1197
1198 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001199 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001200 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1201 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1202 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1203}
1204
deadbeefcb443432016-12-12 11:12:36 -08001205// Test that GetRtpReceiveParameters returns an SSRC.
1206TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1207 EXPECT_TRUE(SetupRecvStream());
1208 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001209 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001210 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001211 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001212}
1213
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001214// Test that if we set/get parameters multiple times, we get the same results.
1215TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1216 EXPECT_TRUE(SetupRecvStream());
1217 cricket::AudioRecvParameters parameters;
1218 parameters.codecs.push_back(kIsacCodec);
1219 parameters.codecs.push_back(kPcmuCodec);
1220 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1221
1222 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001223 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001224
1225 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001226 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001227
1228 // ... And this shouldn't change the params returned by
1229 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001230 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1231 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001232}
1233
deadbeef3bc15102017-04-20 19:25:07 -07001234// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1235// aren't signaled. It should return an empty "RtpEncodingParameters" when
1236// configured to receive an unsignaled stream and no packets have been received
1237// yet, and start returning the SSRC once a packet has been received.
1238TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1239 ASSERT_TRUE(SetupChannel());
1240 // Call necessary methods to configure receiving a default stream as
1241 // soon as it arrives.
1242 cricket::AudioRecvParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
1245 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1246
1247 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1248 // stream. Should return nothing.
1249 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1250
1251 // Set a sink for an unsignaled stream.
1252 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1253 // Value of "0" means "unsignaled stream".
1254 channel_->SetRawAudioSink(0, std::move(fake_sink));
1255
1256 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1257 // in this method means "unsignaled stream".
1258 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1259 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1260 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1261
1262 // Receive PCMU packet (SSRC=1).
1263 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1264
1265 // The |ssrc| member should still be unset.
1266 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1267 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1268 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1269}
1270
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001271// Test that we apply codecs properly.
1272TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001273 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001274 cricket::AudioSendParameters parameters;
1275 parameters.codecs.push_back(kIsacCodec);
1276 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001277 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001278 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001279 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001280 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001281 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1282 EXPECT_EQ(96, send_codec_spec.payload_type);
1283 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1284 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1285 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1286 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001287 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001288}
1289
ossu20a4b3f2017-04-27 02:08:52 -07001290// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1291// AudioSendStream.
1292TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001293 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kIsacCodec);
1296 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001297 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 parameters.codecs[0].id = 96;
1299 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001300 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001301 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001302 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001303 // Calling SetSendCodec again with same codec which is already set.
1304 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001305 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001306 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001307}
1308
ossu20a4b3f2017-04-27 02:08:52 -07001309// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1310// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001311
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001312// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001314 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001315 cricket::AudioSendParameters parameters;
1316 parameters.codecs.push_back(kOpusCodec);
1317 parameters.codecs[0].bitrate = 0;
1318 parameters.codecs[0].clockrate = 50000;
1319 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001320}
1321
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001322// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001324 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001325 cricket::AudioSendParameters parameters;
1326 parameters.codecs.push_back(kOpusCodec);
1327 parameters.codecs[0].bitrate = 0;
1328 parameters.codecs[0].channels = 0;
1329 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330}
1331
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001332// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001334 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001335 cricket::AudioSendParameters parameters;
1336 parameters.codecs.push_back(kOpusCodec);
1337 parameters.codecs[0].bitrate = 0;
1338 parameters.codecs[0].channels = 0;
1339 parameters.codecs[0].params["stereo"] = "1";
1340 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341}
1342
1343// Test that if channel is 1 for opus and there's no stereo, we fail.
1344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kOpusCodec);
1348 parameters.codecs[0].bitrate = 0;
1349 parameters.codecs[0].channels = 1;
1350 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351}
1352
1353// Test that if channel is 1 for opus and stereo=0, we fail.
1354TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001355 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001356 cricket::AudioSendParameters parameters;
1357 parameters.codecs.push_back(kOpusCodec);
1358 parameters.codecs[0].bitrate = 0;
1359 parameters.codecs[0].channels = 1;
1360 parameters.codecs[0].params["stereo"] = "0";
1361 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
1364// Test that if channel is 1 for opus and stereo=1, we fail.
1365TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kOpusCodec);
1369 parameters.codecs[0].bitrate = 0;
1370 parameters.codecs[0].channels = 1;
1371 parameters.codecs[0].params["stereo"] = "1";
1372 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001373}
1374
ossu20a4b3f2017-04-27 02:08:52 -07001375// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001377 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 cricket::AudioSendParameters parameters;
1379 parameters.codecs.push_back(kOpusCodec);
1380 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001381 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001382 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383}
1384
ossu20a4b3f2017-04-27 02:08:52 -07001385// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001387 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 cricket::AudioSendParameters parameters;
1389 parameters.codecs.push_back(kOpusCodec);
1390 parameters.codecs[0].bitrate = 0;
1391 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001392 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001393 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001394}
1395
ossu20a4b3f2017-04-27 02:08:52 -07001396// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001398 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 cricket::AudioSendParameters parameters;
1400 parameters.codecs.push_back(kOpusCodec);
1401 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001402 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001404 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001405 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001406
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001408 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001409 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410}
1411
ossu20a4b3f2017-04-27 02:08:52 -07001412// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kOpusCodec);
1417 parameters.codecs[0].bitrate = 0;
1418 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001419 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001420 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001421}
1422
ossu20a4b3f2017-04-27 02:08:52 -07001423// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001424TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001425 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001426 cricket::AudioSendParameters parameters;
1427 parameters.codecs.push_back(kOpusCodec);
1428 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001429 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001433
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001434 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001435 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001436 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437}
1438
ossu20a4b3f2017-04-27 02:08:52 -07001439// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001441 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 cricket::AudioSendParameters parameters;
1443 parameters.codecs.push_back(kOpusCodec);
1444 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001445 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001446 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1447 EXPECT_EQ(111, spec.payload_type);
1448 EXPECT_EQ(96000, spec.target_bitrate_bps);
1449 EXPECT_EQ("opus", spec.format.name);
1450 EXPECT_EQ(2, spec.format.num_channels);
1451 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
ossu20a4b3f2017-04-27 02:08:52 -07001454// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 30000;
1460 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001462 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
ossu20a4b3f2017-04-27 02:08:52 -07001465// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001471 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001472 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
ossu20a4b3f2017-04-27 02:08:52 -07001475// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001477 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001478 cricket::AudioSendParameters parameters;
1479 parameters.codecs.push_back(kOpusCodec);
1480 parameters.codecs[0].bitrate = 30000;
1481 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001483 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484}
1485
stefan13f1a0a2016-11-30 07:22:58 -08001486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1487 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1488 200000);
1489}
1490
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1492 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake,
1496 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1497 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1498}
1499
1500TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1501 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001505 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001506 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1507 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001508 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001509 SetSendParameters(send_parameters_);
1510 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1511 << "Setting max bitrate should keep previous min bitrate.";
1512 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1513 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001514 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001515}
1516
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001517// Test that we can enable NACK with opus as caller.
1518TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001519 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001520 cricket::AudioSendParameters parameters;
1521 parameters.codecs.push_back(kOpusCodec);
1522 parameters.codecs[0].AddFeedbackParam(
1523 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1524 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001525 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001526 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528}
1529
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001530// Test that we can enable NACK with opus as callee.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001540 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001542
1543 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001544 cricket::StreamParams::CreateLegacy(kSsrcX)));
1545 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001546}
1547
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548// Test that we can enable NACK on receive streams.
1549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001550 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 cricket::AudioSendParameters parameters;
1553 parameters.codecs.push_back(kOpusCodec);
1554 parameters.codecs[0].AddFeedbackParam(
1555 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1556 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001557 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1558 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001559 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001560 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1561 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
1564// Test that we can disable NACK.
1565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].AddFeedbackParam(
1570 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1571 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 parameters.codecs.clear();
1576 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001577 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001578 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579}
1580
1581// Test that we can disable NACK on receive streams.
1582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001583 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001584 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].AddFeedbackParam(
1588 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1589 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1592 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001594 parameters.codecs.clear();
1595 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1598 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599}
1600
1601// Test that NACK is enabled on a new receive stream.
1602TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001603 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001604 cricket::AudioSendParameters parameters;
1605 parameters.codecs.push_back(kIsacCodec);
1606 parameters.codecs.push_back(kCn16000Codec);
1607 parameters.codecs[0].AddFeedbackParam(
1608 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1609 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001611 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612
solenberg2100c0b2017-03-01 11:29:29 -08001613 EXPECT_TRUE(AddRecvStream(kSsrcY));
1614 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1615 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1616 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617}
1618
stefanba4c0e42016-02-04 04:12:24 -08001619TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001620 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001621 cricket::AudioSendParameters send_parameters;
1622 send_parameters.codecs.push_back(kOpusCodec);
1623 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001625
1626 cricket::AudioRecvParameters recv_parameters;
1627 recv_parameters.codecs.push_back(kIsacCodec);
1628 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001629 EXPECT_TRUE(AddRecvStream(kSsrcX));
1630 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001631 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001632 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001633
ossudedfd282016-06-14 07:12:39 -07001634 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001637 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001638 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001639}
1640
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001641// Test that we can switch back and forth between Opus and ISAC with CN.
1642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001644
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001645 cricket::AudioSendParameters opus_parameters;
1646 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001647 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001648 {
ossu20a4b3f2017-04-27 02:08:52 -07001649 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1650 EXPECT_EQ(111, spec.payload_type);
1651 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001652 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001653
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters isac_parameters;
1655 isac_parameters.codecs.push_back(kIsacCodec);
1656 isac_parameters.codecs.push_back(kCn16000Codec);
1657 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001659 {
ossu20a4b3f2017-04-27 02:08:52 -07001660 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1661 EXPECT_EQ(103, spec.payload_type);
1662 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001663 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001664
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001666 {
ossu20a4b3f2017-04-27 02:08:52 -07001667 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1668 EXPECT_EQ(111, spec.payload_type);
1669 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001670 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671}
1672
1673// Test that we handle various ways of specifying bitrate.
1674TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001675 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 cricket::AudioSendParameters parameters;
1677 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001679 {
ossu20a4b3f2017-04-27 02:08:52 -07001680 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1681 EXPECT_EQ(103, spec.payload_type);
1682 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1683 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001684 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001686 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001688 {
ossu20a4b3f2017-04-27 02:08:52 -07001689 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1690 EXPECT_EQ(103, spec.payload_type);
1691 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1692 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001693 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001695 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001696 {
ossu20a4b3f2017-04-27 02:08:52 -07001697 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1698 EXPECT_EQ(103, spec.payload_type);
1699 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1700 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001701 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001704 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001705 {
ossu20a4b3f2017-04-27 02:08:52 -07001706 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1707 EXPECT_EQ(0, spec.payload_type);
1708 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1709 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001710 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001712 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001714 {
ossu20a4b3f2017-04-27 02:08:52 -07001715 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1716 EXPECT_EQ(0, spec.payload_type);
1717 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1718 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001721 parameters.codecs[0] = kOpusCodec;
1722 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001724 {
ossu20a4b3f2017-04-27 02:08:52 -07001725 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1726 EXPECT_EQ(111, spec.payload_type);
1727 EXPECT_STREQ("opus", spec.format.name.c_str());
1728 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001729 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001730}
1731
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001732// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001733TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001734 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters parameters;
1736 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001737}
1738
1739// Test that we can set send codecs even with telephone-event codec as the first
1740// one on the list.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001744 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 parameters.codecs.push_back(kIsacCodec);
1746 parameters.codecs.push_back(kPcmuCodec);
1747 parameters.codecs[0].id = 98; // DTMF
1748 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(96, spec.payload_type);
1752 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001753 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001754}
1755
solenberg31642aa2016-03-14 08:00:37 -07001756// Test that payload type range is limited for telephone-event codec.
1757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001758 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001759 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001760 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001761 parameters.codecs.push_back(kIsacCodec);
1762 parameters.codecs[0].id = 0; // DTMF
1763 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001765 EXPECT_TRUE(channel_->CanInsertDtmf());
1766 parameters.codecs[0].id = 128; // DTMF
1767 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1768 EXPECT_FALSE(channel_->CanInsertDtmf());
1769 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001771 EXPECT_TRUE(channel_->CanInsertDtmf());
1772 parameters.codecs[0].id = -1; // DTMF
1773 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1774 EXPECT_FALSE(channel_->CanInsertDtmf());
1775}
1776
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001777// Test that we can set send codecs even with CN codec as the first
1778// one on the list.
1779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001780 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001781 cricket::AudioSendParameters parameters;
1782 parameters.codecs.push_back(kCn16000Codec);
1783 parameters.codecs.push_back(kIsacCodec);
1784 parameters.codecs.push_back(kPcmuCodec);
1785 parameters.codecs[0].id = 98; // wideband CN
1786 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(96, send_codec_spec.payload_type);
1790 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001791 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792}
1793
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001794// Test that we set VAD and DTMF types correctly as caller.
1795TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001796 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 cricket::AudioSendParameters parameters;
1798 parameters.codecs.push_back(kIsacCodec);
1799 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001801 parameters.codecs.push_back(kCn16000Codec);
1802 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001803 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001804 parameters.codecs[0].id = 96;
1805 parameters.codecs[2].id = 97; // wideband CN
1806 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(96, send_codec_spec.payload_type);
1810 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1811 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001812 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001813 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814}
1815
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001816// Test that we set VAD and DTMF types correctly as callee.
1817TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001818 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001819 cricket::AudioSendParameters parameters;
1820 parameters.codecs.push_back(kIsacCodec);
1821 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001822 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs.push_back(kCn16000Codec);
1824 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001825 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs[0].id = 96;
1827 parameters.codecs[2].id = 97; // wideband CN
1828 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001829 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001830 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001831 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001832
ossu20a4b3f2017-04-27 02:08:52 -07001833 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1834 EXPECT_EQ(96, send_codec_spec.payload_type);
1835 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1836 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001837 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001838 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001839}
1840
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001841// Test that we only apply VAD if we have a CN codec that matches the
1842// send codec clockrate.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001846 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kIsacCodec);
1848 parameters.codecs.push_back(kCn16000Codec);
1849 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001850 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001851 {
ossu20a4b3f2017-04-27 02:08:52 -07001852 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1853 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1854 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001855 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001856 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001857 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001859 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001860 {
ossu20a4b3f2017-04-27 02:08:52 -07001861 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1862 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1863 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001864 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001865 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001866 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001867 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001868 {
ossu20a4b3f2017-04-27 02:08:52 -07001869 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1870 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1871 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001872 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001873 }
Brave Yao5225dd82015-03-26 07:39:19 +08001874 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001875 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001877 {
ossu20a4b3f2017-04-27 02:08:52 -07001878 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1879 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1880 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001881 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882}
1883
1884// Test that we perform case-insensitive matching of codec names.
1885TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001886 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 cricket::AudioSendParameters parameters;
1888 parameters.codecs.push_back(kIsacCodec);
1889 parameters.codecs.push_back(kPcmuCodec);
1890 parameters.codecs.push_back(kCn16000Codec);
1891 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001892 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001893 parameters.codecs[0].name = "iSaC";
1894 parameters.codecs[0].id = 96;
1895 parameters.codecs[2].id = 97; // wideband CN
1896 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001898 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1899 EXPECT_EQ(96, send_codec_spec.payload_type);
1900 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1901 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001902 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001903 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001904}
1905
stefanba4c0e42016-02-04 04:12:24 -08001906class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1907 public:
1908 WebRtcVoiceEngineWithSendSideBweTest()
1909 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1910};
1911
1912TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1913 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001914 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001915 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001916 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1917 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1918 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001919 extension.id);
1920 return;
1921 }
1922 }
1923 FAIL() << "Transport sequence number extension not in header-extension list.";
1924}
1925
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001926// Test support for audio level header extension.
1927TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001928 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001929}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001930TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001931 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001932}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001933
solenbergd4adce42016-11-17 06:26:52 -08001934// Test support for transport sequence number header extension.
1935TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1936 TestSetSendRtpHeaderExtensions(
1937 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001938}
solenbergd4adce42016-11-17 06:26:52 -08001939TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1940 TestSetRecvRtpHeaderExtensions(
1941 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001942}
1943
solenberg1ac56142015-10-13 03:58:19 -07001944// Test that we can create a channel and start sending on it.
1945TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001946 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(send_parameters_);
1948 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001949 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001950 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001951 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001952}
1953
1954// Test that a channel will send if and only if it has a source and is enabled
1955// for sending.
1956TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001957 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001958 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001959 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001960 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001961 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1962 SetAudioSend(kSsrcX, true, &fake_source_);
1963 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1964 SetAudioSend(kSsrcX, true, nullptr);
1965 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001966}
1967
solenberg94218532016-06-16 10:53:22 -07001968// Test that a channel is muted/unmuted.
1969TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1970 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001972 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1973 SetAudioSend(kSsrcX, true, nullptr);
1974 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1975 SetAudioSend(kSsrcX, false, nullptr);
1976 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001977}
1978
solenberg6d6e7c52016-04-13 09:07:30 -07001979// Test that SetSendParameters() does not alter a stream's send state.
1980TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1981 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001983
1984 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001985 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001987
1988 // Changing RTP header extensions will recreate the AudioSendStream.
1989 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001990 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001992 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001993
1994 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001995 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001996 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001997
1998 // Changing RTP header extensions will recreate the AudioSendStream.
1999 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002001 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002002}
2003
solenberg1ac56142015-10-13 03:58:19 -07002004// Test that we can create a channel and start playing out on it.
2005TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002006 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002007 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002008 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002009 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002010 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002011 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012}
2013
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014// Test that we can add and remove send streams.
2015TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2016 SetupForMultiSendStream();
2017
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002018 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002019 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002020
solenbergc96df772015-10-21 13:01:53 -07002021 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002022 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002023 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002024 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002025 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002026 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027 }
tfarina5237aaf2015-11-10 23:44:30 -08002028 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029
solenbergc96df772015-10-21 13:01:53 -07002030 // Delete the send streams.
2031 for (uint32_t ssrc : kSsrcs4) {
2032 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002033 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002034 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035 }
solenbergc96df772015-10-21 13:01:53 -07002036 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037}
2038
2039// Test SetSendCodecs correctly configure the codecs in all send streams.
2040TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2041 SetupForMultiSendStream();
2042
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002044 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002046 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002047 }
2048
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002049 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002051 parameters.codecs.push_back(kIsacCodec);
2052 parameters.codecs.push_back(kCn16000Codec);
2053 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002055
2056 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002057 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002058 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2059 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002060 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2061 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2062 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002063 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002064 }
2065
minyue7a973442016-10-20 03:27:12 -07002066 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002067 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002069 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002070 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2071 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002072 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2073 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2074 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075 }
2076}
2077
2078// Test we can SetSend on all send streams correctly.
2079TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2080 SetupForMultiSendStream();
2081
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002082 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002083 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002084 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002085 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002086 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002087 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089
2090 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002091 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002092 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002093 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002094 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002095 }
2096
2097 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002098 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002099 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002100 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002101 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102 }
2103}
2104
2105// Test we can set the correct statistics on all send streams.
2106TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2107 SetupForMultiSendStream();
2108
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002110 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002111 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002112 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 }
solenberg85a04962015-10-27 03:35:21 -07002114
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002115 // Create a receive stream to check that none of the send streams end up in
2116 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002117 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002118
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002119 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002121 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002122 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123
solenberg85a04962015-10-27 03:35:21 -07002124 // Check stats for the added streams.
2125 {
2126 cricket::VoiceMediaInfo info;
2127 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128
solenberg85a04962015-10-27 03:35:21 -07002129 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002130 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002131 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002132 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002133 }
hbos1acfbd22016-11-17 23:43:29 -08002134 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002135
2136 // We have added one receive stream. We should see empty stats.
2137 EXPECT_EQ(info.receivers.size(), 1u);
2138 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 }
solenberg1ac56142015-10-13 03:58:19 -07002140
solenberg2100c0b2017-03-01 11:29:29 -08002141 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002142 {
2143 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002145 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002146 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002147 EXPECT_EQ(0u, info.receivers.size());
2148 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002149
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002150 // Deliver a new packet - a default receive stream should be created and we
2151 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002152 {
2153 cricket::VoiceMediaInfo info;
2154 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2155 SetAudioReceiveStreamStats();
2156 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002157 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002158 EXPECT_EQ(1u, info.receivers.size());
2159 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002160 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002161 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162}
2163
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164// Test that we can add and remove receive streams, and do proper send/playout.
2165// We can receive on multiple streams while sending one stream.
2166TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002167 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168
solenberg1ac56142015-10-13 03:58:19 -07002169 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002170 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002171 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002172
solenberg1ac56142015-10-13 03:58:19 -07002173 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002174 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002175 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002176 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177
solenberg1ac56142015-10-13 03:58:19 -07002178 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002179 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180
2181 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2183 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2184 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
2186 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002187 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002188 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002189
2190 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002191 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002192 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2193 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194
aleloi84ef6152016-08-04 05:28:21 -07002195 // Restart playout and make sure recv streams are played out.
2196 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002197 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2198 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002199
aleloi84ef6152016-08-04 05:28:21 -07002200 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2202 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002203}
2204
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002205// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002206// and start sending on it.
2207TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002208 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002209 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2210 EXPECT_CALL(apm_gc_,
2211 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002212 SetSendParameters(send_parameters_);
2213 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002215 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002217}
2218
wu@webrtc.org97077a32013-10-25 21:18:33 +00002219TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002220 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002221 EXPECT_CALL(adm_,
2222 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002223 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2224 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002225 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2226 send_parameters_.options.tx_agc_digital_compression_gain =
2227 rtc::Optional<uint16_t>(9);
2228 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2229 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002230 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2231 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2232 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002233 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002234
2235 // Check interaction with adjust_agc_delta. Both should be respected, for
2236 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002237 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002238 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002239 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002240}
2241
wu@webrtc.org97077a32013-10-25 21:18:33 +00002242TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002243 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002244 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2245 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002246 send_parameters_.options.recording_sample_rate =
2247 rtc::Optional<uint32_t>(48000);
2248 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002249 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002250}
2251
minyue6b825df2016-10-31 04:08:32 -07002252TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2253 EXPECT_TRUE(SetupSendStream());
2254 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2255 send_parameters_.options.audio_network_adaptor_config =
2256 rtc::Optional<std::string>("1234");
2257 SetSendParameters(send_parameters_);
2258 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002259 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002260}
2261
2262TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2263 EXPECT_TRUE(SetupSendStream());
2264 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2265 send_parameters_.options.audio_network_adaptor_config =
2266 rtc::Optional<std::string>("1234");
2267 SetSendParameters(send_parameters_);
2268 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002269 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002270 cricket::AudioOptions options;
2271 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002272 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002274}
2275
2276TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2277 EXPECT_TRUE(SetupSendStream());
2278 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2279 send_parameters_.options.audio_network_adaptor_config =
2280 rtc::Optional<std::string>("1234");
2281 SetSendParameters(send_parameters_);
2282 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002283 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002284 const int initial_num = call_.GetNumCreatedSendStreams();
2285 cricket::AudioOptions options;
2286 options.audio_network_adaptor = rtc::Optional<bool>();
2287 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2288 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002289 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002290 // AudioSendStream not expected to be recreated.
2291 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2292 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002293 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002294}
2295
michaelt6672b262017-01-11 10:17:59 -08002296class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2297 : public WebRtcVoiceEngineTestFake {
2298 public:
2299 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2300 : WebRtcVoiceEngineTestFake(
2301 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2302 "Enabled/") {}
2303};
2304
2305TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2306 EXPECT_TRUE(SetupSendStream());
2307 cricket::AudioSendParameters parameters;
2308 parameters.codecs.push_back(kOpusCodec);
2309 SetSendParameters(parameters);
2310 const int initial_num = call_.GetNumCreatedSendStreams();
2311 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2312
2313 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2314 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002315 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2316 constexpr int kMinOverheadBps =
2317 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002318
2319 constexpr int kOpusMinBitrateBps = 6000;
2320 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002321 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002322 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002323 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002324 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002325
2326 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2327 parameters.options.audio_network_adaptor_config =
2328 rtc::Optional<std::string>("1234");
2329 SetSendParameters(parameters);
2330
ossu11bfc532017-02-16 05:37:06 -08002331 constexpr int kMinOverheadWithAnaBps =
2332 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002333
2334 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002335 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002336
minyuececec102017-03-27 13:04:25 -07002337 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002338 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002339}
2340
minyuececec102017-03-27 13:04:25 -07002341// This test is similar to
2342// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2343// additional field trial.
2344TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2345 SetRtpSendParameterUpdatesMaxBitrate) {
2346 EXPECT_TRUE(SetupSendStream());
2347 cricket::AudioSendParameters send_parameters;
2348 send_parameters.codecs.push_back(kOpusCodec);
2349 SetSendParameters(send_parameters);
2350
2351 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2352 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2353 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2354
2355 constexpr int kMaxBitrateBps = 6000;
2356 rtp_parameters.encodings[0].max_bitrate_bps =
2357 rtc::Optional<int>(kMaxBitrateBps);
2358 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2359
2360 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2361#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2362 constexpr int kMinOverhead = 3333;
2363#else
2364 constexpr int kMinOverhead = 6666;
2365#endif
2366 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2367}
2368
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002370// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002371TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002372 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002373 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374}
2375
2376TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2377 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002378 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002379 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002380 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002381 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002382 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002383 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002384 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385
solenberg85a04962015-10-27 03:35:21 -07002386 // Check stats for the added streams.
2387 {
2388 cricket::VoiceMediaInfo info;
2389 EXPECT_EQ(true, channel_->GetStats(&info));
2390
2391 // We have added one send stream. We should see the stats we've set.
2392 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002393 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002394 // We have added one receive stream. We should see empty stats.
2395 EXPECT_EQ(info.receivers.size(), 1u);
2396 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2397 }
solenberg1ac56142015-10-13 03:58:19 -07002398
solenberg566ef242015-11-06 15:34:49 -08002399 // Start sending - this affects some reported stats.
2400 {
2401 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002402 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002403 EXPECT_EQ(true, channel_->GetStats(&info));
2404 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002405 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002406 }
2407
solenberg2100c0b2017-03-01 11:29:29 -08002408 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002409 {
2410 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002411 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002412 EXPECT_EQ(true, channel_->GetStats(&info));
2413 EXPECT_EQ(1u, info.senders.size());
2414 EXPECT_EQ(0u, info.receivers.size());
2415 }
solenberg1ac56142015-10-13 03:58:19 -07002416
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002417 // Deliver a new packet - a default receive stream should be created and we
2418 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002419 {
2420 cricket::VoiceMediaInfo info;
2421 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2422 SetAudioReceiveStreamStats();
2423 EXPECT_EQ(true, channel_->GetStats(&info));
2424 EXPECT_EQ(1u, info.senders.size());
2425 EXPECT_EQ(1u, info.receivers.size());
2426 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002427 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002428 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429}
2430
2431// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002432// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002434 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002435 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2436 EXPECT_TRUE(AddRecvStream(kSsrcY));
2437 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438}
2439
2440// Test that the local SSRC is the same on sending and receiving channels if the
2441// receive channel is created before the send channel.
2442TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002443 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002444 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002446 cricket::StreamParams::CreateLegacy(kSsrcX)));
2447 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2448 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449}
2450
2451// Test that we can properly receive packets.
2452TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002453 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002454 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002456
2457 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2458 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459}
2460
2461// Test that we can properly receive packets on multiple streams.
2462TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002463 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002464 const uint32_t ssrc1 = 1;
2465 const uint32_t ssrc2 = 2;
2466 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002467 EXPECT_TRUE(AddRecvStream(ssrc1));
2468 EXPECT_TRUE(AddRecvStream(ssrc2));
2469 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002471 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002472 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002474 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475 }
mflodman3d7db262016-04-29 00:57:13 -07002476
2477 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2478 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2479 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2480
2481 EXPECT_EQ(s1.received_packets(), 0);
2482 EXPECT_EQ(s2.received_packets(), 0);
2483 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_EQ(s1.received_packets(), 0);
2487 EXPECT_EQ(s2.received_packets(), 0);
2488 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002489
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002491 EXPECT_EQ(s1.received_packets(), 1);
2492 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2493 EXPECT_EQ(s2.received_packets(), 0);
2494 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002495
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_EQ(s1.received_packets(), 1);
2498 EXPECT_EQ(s2.received_packets(), 1);
2499 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2500 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002501
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002503 EXPECT_EQ(s1.received_packets(), 1);
2504 EXPECT_EQ(s2.received_packets(), 1);
2505 EXPECT_EQ(s3.received_packets(), 1);
2506 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002507
mflodman3d7db262016-04-29 00:57:13 -07002508 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2509 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2510 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511}
2512
solenberg2100c0b2017-03-01 11:29:29 -08002513// Test that receiving on an unsignaled stream works (a stream is created).
2514TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002515 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002516 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2517
solenberg7e63ef02015-11-20 00:19:43 -08002518 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002519
2520 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2522 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002523}
2524
solenberg2100c0b2017-03-01 11:29:29 -08002525// Test that receiving N unsignaled stream works (streams will be created), and
2526// that packets are forwarded to them all.
2527TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002528 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002529 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002530 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2531
solenberg2100c0b2017-03-01 11:29:29 -08002532 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002533 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002534 rtc::SetBE32(&packet[8], ssrc);
2535 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002536
solenberg2100c0b2017-03-01 11:29:29 -08002537 // Verify we have one new stream for each loop iteration.
2538 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2540 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002541 }
mflodman3d7db262016-04-29 00:57:13 -07002542
solenberg2100c0b2017-03-01 11:29:29 -08002543 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002544 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002545 rtc::SetBE32(&packet[8], ssrc);
2546 DeliverPacket(packet, sizeof(packet));
2547
solenbergebb349d2017-03-13 05:46:15 -07002548 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002549 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2550 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2551 }
2552
2553 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2554 constexpr uint32_t kAnotherSsrc = 667;
2555 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002556 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002557
2558 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002559 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002560 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002561 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002562 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2563 EXPECT_EQ(2, streams[i]->received_packets());
2564 }
2565 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2566 EXPECT_EQ(1, streams[i]->received_packets());
2567 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002568 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002569}
2570
solenberg2100c0b2017-03-01 11:29:29 -08002571// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002572// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002573TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002574 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002575 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002576 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2577
2578 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002579 const uint32_t signaled_ssrc = 1;
2580 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002581 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002582 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002583 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2584 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002585 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002586
2587 // Note that the first unknown SSRC cannot be 0, because we only support
2588 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002589 const uint32_t unsignaled_ssrc = 7011;
2590 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002591 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002592 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2593 packet, sizeof(packet)));
2594 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2595
2596 DeliverPacket(packet, sizeof(packet));
2597 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2598
2599 rtc::SetBE32(&packet[8], signaled_ssrc);
2600 DeliverPacket(packet, sizeof(packet));
2601 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2602 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002603}
2604
solenberg4904fb62017-02-17 12:01:14 -08002605// Two tests to verify that adding a receive stream with the same SSRC as a
2606// previously added unsignaled stream will only recreate underlying stream
2607// objects if the stream parameters have changed.
2608TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2609 EXPECT_TRUE(SetupChannel());
2610
2611 // Spawn unsignaled stream with SSRC=1.
2612 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2613 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2614 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2615 sizeof(kPcmuFrame)));
2616
2617 // Verify that the underlying stream object in Call is not recreated when a
2618 // stream with SSRC=1 is added.
2619 const auto& streams = call_.GetAudioReceiveStreams();
2620 EXPECT_EQ(1, streams.size());
2621 int audio_receive_stream_id = streams.front()->id();
2622 EXPECT_TRUE(AddRecvStream(1));
2623 EXPECT_EQ(1, streams.size());
2624 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2625}
2626
2627TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2628 EXPECT_TRUE(SetupChannel());
2629
2630 // Spawn unsignaled stream with SSRC=1.
2631 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2632 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2633 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2634 sizeof(kPcmuFrame)));
2635
2636 // Verify that the underlying stream object in Call *is* recreated when a
2637 // stream with SSRC=1 is added, and which has changed stream parameters.
2638 const auto& streams = call_.GetAudioReceiveStreams();
2639 EXPECT_EQ(1, streams.size());
2640 int audio_receive_stream_id = streams.front()->id();
2641 cricket::StreamParams stream_params;
2642 stream_params.ssrcs.push_back(1);
2643 stream_params.sync_label = "sync_label";
2644 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2645 EXPECT_EQ(1, streams.size());
2646 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2647}
2648
solenberg0a617e22015-10-20 15:49:38 -07002649// Test that we properly handle failures to add a receive stream.
2650TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002653 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002654}
2655
solenberg0a617e22015-10-20 15:49:38 -07002656// Test that we properly handle failures to add a send stream.
2657TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002658 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002659 voe_.set_fail_create_channel(true);
2660 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2661}
2662
solenberg1ac56142015-10-13 03:58:19 -07002663// Test that AddRecvStream creates new stream.
2664TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002665 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002666 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002667 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002668 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669}
2670
2671// Test that after adding a recv stream, we do not decode more codecs than
2672// those previously passed into SetRecvCodecs.
2673TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002675 cricket::AudioRecvParameters parameters;
2676 parameters.codecs.push_back(kIsacCodec);
2677 parameters.codecs.push_back(kPcmuCodec);
2678 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002679 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002680 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2681 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2682 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002683}
2684
2685// Test that we properly clean up any streams that were added, even if
2686// not explicitly removed.
2687TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002689 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002690 EXPECT_TRUE(AddRecvStream(1));
2691 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002692 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2693 delete channel_;
2694 channel_ = NULL;
2695 EXPECT_EQ(0, voe_.GetNumChannels());
2696}
2697
wu@webrtc.org78187522013-10-07 23:32:02 +00002698TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002699 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002700 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002701}
2702
2703TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002704 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002705 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002706 // Manually delete channel to simulate a failure.
2707 int channel = voe_.GetLastChannel();
2708 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2709 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002710 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002711 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002712 EXPECT_NE(channel, new_channel);
2713 // The last created channel is deleted too.
2714 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002715}
2716
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002717// Test the InsertDtmf on default send stream as caller.
2718TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002719 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720}
2721
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002722// Test the InsertDtmf on default send stream as callee
2723TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002724 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002725}
2726
2727// Test the InsertDtmf on specified send stream as caller.
2728TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002729 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002730}
2731
2732// Test the InsertDtmf on specified send stream as callee.
2733TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002734 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735}
2736
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002738 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002739 EXPECT_CALL(adm_,
2740 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2741 EXPECT_CALL(adm_,
2742 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2743 EXPECT_CALL(adm_,
2744 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002745
solenberg246b8172015-12-08 09:50:23 -08002746 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2747 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748
solenberg246b8172015-12-08 09:50:23 -08002749 // Nothing set in AudioOptions, so everything should be as default.
2750 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002752 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002753 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2754 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755
2756 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002757 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2758 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002759 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761
2762 // Turn echo cancellation back on, with settings, and make sure
2763 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002764 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2765 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002766 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002767 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002769 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2770 // control.
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002773 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002775
2776 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002777 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002779 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2780 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2781 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002783
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002784 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002787 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002788 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002789
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002790 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002791 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2794 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002795 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002796 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797
2798 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002799 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2800 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2802 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002803 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2804 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002805 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002806
2807 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002808 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2814 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002815 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2816 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2817 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2818 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002819 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002820 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002821
solenberg1ac56142015-10-13 03:58:19 -07002822 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002823 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2824 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2825 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2828 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2829 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002830 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831}
2832
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002833TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002834 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002835 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002836 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002837 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002838 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002839 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002840 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002841 EXPECT_CALL(adm_,
2842 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2843 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2844 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002845 webrtc::AudioProcessing::Config apm_config;
2846 EXPECT_CALL(*apm_, GetConfig())
2847 .Times(10)
2848 .WillRepeatedly(ReturnPointee(&apm_config));
2849 EXPECT_CALL(*apm_, ApplyConfig(_))
2850 .Times(10)
2851 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002852 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002853
kwiberg686a8ef2016-02-26 03:00:35 -08002854 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002855 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002856 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002857 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002858 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002859 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860
2861 // Have to add a stream to make SetSend work.
2862 cricket::StreamParams stream1;
2863 stream1.ssrcs.push_back(1);
2864 channel1->AddSendStream(stream1);
2865 cricket::StreamParams stream2;
2866 stream2.ssrcs.push_back(2);
2867 channel2->AddSendStream(stream2);
2868
2869 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002870 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002871 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2872 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2873 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2875 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2876 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2877 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2878 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002879 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002880 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002881 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002882 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883
2884 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002885 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002886 parameters_options_no_ns.options.noise_suppression =
2887 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002893 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002894 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002895 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2896 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2897 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002898 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899
2900 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002901 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002902 parameters_options_no_agc.options.auto_gain_control =
2903 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2905 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2906 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2908 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002909 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002910 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2911 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2912 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002913 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914
solenberg76377c52017-02-21 00:54:31 -08002915 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2916 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2918 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002920 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921
solenberg76377c52017-02-21 00:54:31 -08002922 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2923 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2926 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002927 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2930 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2931 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2932 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2933 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002934 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002937 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2938 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002939 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002940 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002941 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002942 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002943 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2944 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2945 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2946 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2947 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002948 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002949 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2950 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2951 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002952 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953}
2954
wu@webrtc.orgde305012013-10-31 15:40:38 +00002955// This test verifies DSCP settings are properly applied on voice media channel.
2956TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002958 cricket::FakeNetworkInterface network_interface;
2959 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002960 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002961
peahb1c9d1d2017-07-25 15:45:24 -07002962 webrtc::AudioProcessing::Config apm_config;
2963 EXPECT_CALL(*apm_, GetConfig())
2964 .Times(3)
2965 .WillRepeatedly(ReturnPointee(&apm_config));
2966 EXPECT_CALL(*apm_, ApplyConfig(_))
2967 .Times(3)
2968 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002969 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002970
solenbergbc37fc82016-04-04 09:54:44 -07002971 channel.reset(
2972 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002973 channel->SetInterface(&network_interface);
2974 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2975 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2976
2977 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002978 channel.reset(
2979 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002980 channel->SetInterface(&network_interface);
2981 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2982
2983 // Verify that setting the option to false resets the
2984 // DiffServCodePoint.
2985 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002986 channel.reset(
2987 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002988 channel->SetInterface(&network_interface);
2989 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2990 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2991
2992 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002993}
2994
solenberg1ac56142015-10-13 03:58:19 -07002995TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002996 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997 cricket::WebRtcVoiceMediaChannel* media_channel =
2998 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002999 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003000 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003001 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3003 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3004 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003005 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003006 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007}
3008
solenberg1ac56142015-10-13 03:58:19 -07003009TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003010 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003012 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3013 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3014 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003015 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003016 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003017 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3018 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003019 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003020 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003021 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003022 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023}
3024
solenberg4bac9c52015-10-09 02:32:53 -07003025TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003026 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003027 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003029 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003030 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003031 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3032 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3033 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003034}
3035
solenberg2100c0b2017-03-01 11:29:29 -08003036TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003037 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003038
3039 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003040 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003041 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3042
3043 // Should remember the volume "2" which will be set on new unsignaled streams,
3044 // and also set the gain to 2 on existing unsignaled streams.
3045 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3046 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3047
3048 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3049 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3050 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3051 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3052 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3053 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3054
3055 // Setting gain with SSRC=0 should affect all unsignaled streams.
3056 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003057 if (kMaxUnsignaledRecvStreams > 1) {
3058 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3059 }
solenberg2100c0b2017-03-01 11:29:29 -08003060 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3061
3062 // Setting gain on an individual stream affects only that.
3063 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003064 if (kMaxUnsignaledRecvStreams > 1) {
3065 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3066 }
solenberg2100c0b2017-03-01 11:29:29 -08003067 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003068}
3069
pbos8fc7fa72015-07-15 08:02:58 -07003070TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003071 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003072 const std::string kSyncLabel = "AvSyncLabel";
3073
solenbergff976312016-03-30 23:28:51 -07003074 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003075 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3076 sp.sync_label = kSyncLabel;
3077 // Creating two channels to make sure that sync label is set properly for both
3078 // the default voice channel and following ones.
3079 EXPECT_TRUE(channel_->AddRecvStream(sp));
3080 sp.ssrcs[0] += 1;
3081 EXPECT_TRUE(channel_->AddRecvStream(sp));
3082
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003084 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003085 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003086 << "SyncGroup should be set based on sync_label";
3087 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003088 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003089 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003090}
3091
solenberg3a941542015-11-16 07:34:50 -08003092// TODO(solenberg): Remove, once recv streams are configured through Call.
3093// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003094TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 // Test that setting the header extensions results in the expected state
3096 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003097 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 ssrcs.push_back(223);
3099 ssrcs.push_back(224);
3100
solenbergff976312016-03-30 23:28:51 -07003101 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003102 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003103 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003104 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 cricket::StreamParams::CreateLegacy(ssrc)));
3106 }
3107
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003108 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003109 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003110 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003111 EXPECT_NE(nullptr, s);
3112 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3113 }
3114
3115 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003116 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003117 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003118 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003119 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003120 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003121 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003122 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123 EXPECT_NE(nullptr, s);
3124 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003125 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3126 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 for (const auto& s_ext : s_exts) {
3128 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003129 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 }
3131 }
3132 }
3133 }
3134
3135 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003136 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003137 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003138 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 EXPECT_NE(nullptr, s);
3140 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3141 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003142}
3143
3144TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3145 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003146 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003147 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003148 static const unsigned char kRtcp[] = {
3149 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3150 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3153 };
jbaucheec21bd2016-03-20 06:15:43 -07003154 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155
solenbergff976312016-03-30 23:28:51 -07003156 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003157 cricket::WebRtcVoiceMediaChannel* media_channel =
3158 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003159 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003160 EXPECT_TRUE(media_channel->AddRecvStream(
3161 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3162
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003163 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003164 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003165 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003166 EXPECT_EQ(0, s->received_packets());
3167 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3168 EXPECT_EQ(1, s->received_packets());
3169 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3170 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003171}
Minyue2013aec2015-05-13 14:14:42 +02003172
solenberg0a617e22015-10-20 15:49:38 -07003173// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003174// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003175TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003177 EXPECT_TRUE(AddRecvStream(kSsrcY));
3178 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003179 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003180 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3181 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3182 EXPECT_TRUE(AddRecvStream(kSsrcW));
3183 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003184}
3185
solenberg7602aab2016-11-14 11:30:07 -08003186TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3187 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003188 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003189 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003190 cricket::StreamParams::CreateLegacy(kSsrcY)));
3191 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3192 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3193 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003194 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003195 cricket::StreamParams::CreateLegacy(kSsrcW)));
3196 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3197 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003198}
stefan658910c2015-09-03 05:48:32 -07003199
deadbeef884f5852016-01-15 09:20:04 -08003200TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003201 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003202 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3203 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003204
3205 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003206 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3207 EXPECT_TRUE(AddRecvStream(kSsrcX));
3208 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003209
3210 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003211 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3212 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003213
3214 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003215 channel_->SetRawAudioSink(kSsrcX, nullptr);
3216 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003217}
3218
solenberg2100c0b2017-03-01 11:29:29 -08003219TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003220 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003221 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3222 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003223 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3224 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003225
3226 // Should be able to set a default sink even when no stream exists.
3227 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3228
solenberg2100c0b2017-03-01 11:29:29 -08003229 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3230 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003231 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003232 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003233
3234 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003235 channel_->SetRawAudioSink(kSsrc0, nullptr);
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003237
3238 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003239 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3240 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003241
3242 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003243 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003244 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3246
3247 // Spawn another unsignaled stream - it should be assigned the default sink
3248 // and the previous unsignaled stream should lose it.
3249 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3250 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3251 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3252 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003253 if (kMaxUnsignaledRecvStreams > 1) {
3254 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3255 }
solenberg2100c0b2017-03-01 11:29:29 -08003256 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3257
3258 // Reset the default sink - the second unsignaled stream should lose it.
3259 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003260 if (kMaxUnsignaledRecvStreams > 1) {
3261 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3262 }
solenberg2100c0b2017-03-01 11:29:29 -08003263 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3264
3265 // Try setting the default sink while two streams exists.
3266 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003267 if (kMaxUnsignaledRecvStreams > 1) {
3268 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3269 }
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3271
3272 // Try setting the sink for the first unsignaled stream using its known SSRC.
3273 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003274 if (kMaxUnsignaledRecvStreams > 1) {
3275 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3276 }
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003278 if (kMaxUnsignaledRecvStreams > 1) {
3279 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3280 }
deadbeef884f5852016-01-15 09:20:04 -08003281}
3282
skvlad7a43d252016-03-22 15:32:27 -07003283// Test that, just like the video channel, the voice channel communicates the
3284// network state to the call.
3285TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003286 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003287
3288 EXPECT_EQ(webrtc::kNetworkUp,
3289 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3290 EXPECT_EQ(webrtc::kNetworkUp,
3291 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3292
3293 channel_->OnReadyToSend(false);
3294 EXPECT_EQ(webrtc::kNetworkDown,
3295 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3296 EXPECT_EQ(webrtc::kNetworkUp,
3297 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3298
3299 channel_->OnReadyToSend(true);
3300 EXPECT_EQ(webrtc::kNetworkUp,
3301 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3302 EXPECT_EQ(webrtc::kNetworkUp,
3303 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3304}
3305
aleloi18e0b672016-10-04 02:45:47 -07003306// Test that playout is still started after changing parameters
3307TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3308 SetupRecvStream();
3309 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003310 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003311
3312 // Changing RTP header extensions will recreate the AudioReceiveStream.
3313 cricket::AudioRecvParameters parameters;
3314 parameters.extensions.push_back(
3315 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3316 channel_->SetRecvParameters(parameters);
3317
solenberg2100c0b2017-03-01 11:29:29 -08003318 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003319}
3320
stefan658910c2015-09-03 05:48:32 -07003321// Tests that the library initializes and shuts down properly.
3322TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003323 // If the VoiceEngine wants to gather available codecs early, that's fine but
3324 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003325 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003326 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3327 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003328 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003329 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003330 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003331 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003332 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003333 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003334 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003335 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3336 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003337 EXPECT_TRUE(channel != nullptr);
3338 delete channel;
solenbergff976312016-03-30 23:28:51 -07003339}
stefan658910c2015-09-03 05:48:32 -07003340
solenbergff976312016-03-30 23:28:51 -07003341// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003342TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3343 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003344 EXPECT_CALL(adm, AddRef()).Times(3);
3345 EXPECT_CALL(adm, Release())
3346 .Times(3)
3347 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003348 {
peaha9cc40b2017-06-29 08:32:09 -07003349 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3350 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003351 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003352 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003353 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003354 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003355 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003356 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003357 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003358 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3359 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3360 EXPECT_TRUE(channel != nullptr);
3361 delete channel;
3362 }
stefan658910c2015-09-03 05:48:32 -07003363}
3364
ossu20a4b3f2017-04-27 02:08:52 -07003365// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3366TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003367 // TODO(ossu): Why are the payload types of codecs with non-static payload
3368 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003369 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003370 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3371 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003372 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003373 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003374 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003375 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003376 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003377 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3378 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3379 (clockrate == 0 || codec.clockrate == clockrate);
3380 };
3381 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003382 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003383 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003384 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003385 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003386 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003387 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003388 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003389 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003390 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003391 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003392 EXPECT_EQ(126, codec.id);
3393 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3394 // Remove these checks once both send and receive side assigns payload types
3395 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003396 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003397 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003398 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003399 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003400 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003401 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003402 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003403 EXPECT_EQ(111, codec.id);
3404 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3405 EXPECT_EQ("10", codec.params.find("minptime")->second);
3406 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3407 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003408 }
3409 }
stefan658910c2015-09-03 05:48:32 -07003410}
3411
3412// Tests that VoE supports at least 32 channels
3413TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003414 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003415 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3416 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003417 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003418 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003419 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003420 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003421 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003422 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003423 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003424
3425 cricket::VoiceMediaChannel* channels[32];
3426 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003427 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003428 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3429 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003430 if (!channel)
3431 break;
stefan658910c2015-09-03 05:48:32 -07003432 channels[num_channels++] = channel;
3433 }
3434
tfarina5237aaf2015-11-10 23:44:30 -08003435 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003436 EXPECT_EQ(expected, num_channels);
3437
3438 while (num_channels > 0) {
3439 delete channels[--num_channels];
3440 }
stefan658910c2015-09-03 05:48:32 -07003441}
3442
3443// Test that we set our preferred codecs properly.
3444TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003445 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3446 // - Check that our builtin codecs are usable by Channel.
3447 // - The codecs provided by the engine is usable by Channel.
3448 // It does not check that the codecs in the RecvParameters are actually
3449 // what we sent in - though it's probably reasonable to expect so, if
3450 // SetRecvParameters returns true.
3451 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003452 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003453 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3454 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003455 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003456 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003457 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003458 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003459 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003460 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003461 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003462 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3463 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003464 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003465 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003466 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003467}
ossu9def8002017-02-09 05:14:32 -08003468
3469TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3470 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003471 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3472 {48000, 2, 16000, 10000, 20000}};
3473 spec1.info.allow_comfort_noise = false;
3474 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003475 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003476 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3477 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003478 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003479 specs.push_back(webrtc::AudioCodecSpec{
3480 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3481 {16000, 1, 13300}});
3482 specs.push_back(
3483 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3484 specs.push_back(
3485 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003486
ossueb1fde42017-05-02 06:46:30 -07003487 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3488 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3489 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003490 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003491 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003492 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003493 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003494
peaha9cc40b2017-06-29 08:32:09 -07003495 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3496 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003497 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003498 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003499 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003500 auto codecs = engine.recv_codecs();
3501 EXPECT_EQ(11, codecs.size());
3502
3503 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3504 // check the actual values safely, to provide better test results.
3505 auto get_codec =
3506 [&codecs](size_t index) -> const cricket::AudioCodec& {
3507 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3508 if (codecs.size() > index)
3509 return codecs[index];
3510 return missing_codec;
3511 };
3512
3513 // Ensure the general codecs are generated first and in order.
3514 for (size_t i = 0; i != specs.size(); ++i) {
3515 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3516 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3517 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3518 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3519 }
3520
3521 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003522 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003523 auto find_codec =
3524 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3525 for (size_t i = 0; i != codecs.size(); ++i) {
3526 const cricket::AudioCodec& codec = codecs[i];
3527 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3528 codec.clockrate == format.clockrate_hz &&
3529 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003530 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003531 }
3532 }
3533 return -1;
3534 };
3535
3536 // Ensure all supplementary codecs are generated last. Their internal ordering
3537 // is not important.
3538 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3539 const int num_specs = static_cast<int>(specs.size());
3540 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3541 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3542 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3543 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3544 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3545 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3546 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3547}