blob: 2d41ecd43b513a4c620bd1c41ea9bd4dfd0bb55e [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
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080014#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000015#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080016#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070018#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakemediaengine.h"
20#include "webrtc/media/base/fakenetworkinterface.h"
21#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080022#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010023#include "webrtc/media/engine/fakewebrtccall.h"
24#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
25#include "webrtc/media/engine/webrtcvoiceengine.h"
ossu29b1a8d2016-06-13 07:34:51 -070026#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070027#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070028#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080029#include "webrtc/pc/channel.h"
30#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080031#include "webrtc/test/gtest.h"
32#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
solenbergbc37fc82016-04-04 09:54:44 -070034using testing::Return;
35using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000036
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020037namespace {
38
solenbergebb349d2017-03-13 05:46:15 -070039constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
40
deadbeef67cf2c12016-04-13 10:07:16 -070041const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
42const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
43const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
44const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
45const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070046const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
47const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080048const cricket::AudioCodec
49 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
50const cricket::AudioCodec
51 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
52
solenberg2100c0b2017-03-01 11:29:29 -080053const uint32_t kSsrc0 = 0;
54const uint32_t kSsrc1 = 1;
55const uint32_t kSsrcX = 0x99;
56const uint32_t kSsrcY = 0x17;
57const uint32_t kSsrcZ = 0x42;
58const uint32_t kSsrcW = 0x02;
59const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
solenberg971cab02016-06-14 10:02:41 -070061constexpr int kRtpHistoryMs = 5000;
62
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063class FakeVoEWrapper : public cricket::VoEWrapper {
64 public:
65 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg76377c52017-02-21 00:54:31 -080066 : cricket::VoEWrapper(engine, // base
solenberg9a5f032222017-03-15 06:14:12 -070067 engine) { // codec
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 }
69};
skvlad11a9cbf2016-10-07 11:53:05 -070070
solenberg76377c52017-02-21 00:54:31 -080071class MockTransmitMixer : public webrtc::voe::TransmitMixer {
72 public:
73 MockTransmitMixer() = default;
74 virtual ~MockTransmitMixer() = default;
75
76 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
77};
solenberg9a5f032222017-03-15 06:14:12 -070078
79void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
80 RTC_DCHECK(adm);
81 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
82 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
83#if !defined(WEBRTC_IOS)
84 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
85 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
86 ChannelType::kChannelBoth)).WillOnce(Return(0));
87#if defined(WEBRTC_WIN)
88 EXPECT_CALL(*adm, SetRecordingDevice(
89 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
90 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
91 .WillOnce(Return(0));
92#else
93 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
94#endif // #if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
96 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
97 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
98 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
99#if defined(WEBRTC_WIN)
100 EXPECT_CALL(*adm, SetPlayoutDevice(
101 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
102 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
103 .WillOnce(Return(0));
104#else
105 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
106#endif // #if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
108 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
109 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
110#endif // #if !defined(WEBRTC_IOS)
111 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
115}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200116} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117
solenbergff976312016-03-30 23:28:51 -0700118// Tests that our stub library "works".
119TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700120 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700121 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700122 StrictMock<webrtc::test::MockAudioProcessing> apm;
123 EXPECT_CALL(apm, ApplyConfig(testing::_));
124 EXPECT_CALL(apm, SetExtraOptions(testing::_));
125 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800126 StrictMock<MockTransmitMixer> transmit_mixer;
127 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
128 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700129 EXPECT_FALSE(voe.IsInited());
130 {
ossuc54071d2016-08-17 02:45:41 -0700131 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -0800132 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700133 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700134 EXPECT_TRUE(voe.IsInited());
135 }
136 EXPECT_FALSE(voe.IsInited());
137}
138
deadbeef884f5852016-01-15 09:20:04 -0800139class FakeAudioSink : public webrtc::AudioSinkInterface {
140 public:
141 void OnData(const Data& audio) override {}
142};
143
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800144class FakeAudioSource : public cricket::AudioSource {
145 void SetSink(Sink* sink) override {}
146};
147
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148class WebRtcVoiceEngineTestFake : public testing::Test {
149 public:
stefanba4c0e42016-02-04 04:12:24 -0800150 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
151
152 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800153 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
154 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
155 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700156 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800157 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700158 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800159 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700160 EXPECT_CALL(apm_, ApplyConfig(testing::_));
161 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
162 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800163 // Default Options.
164 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
165 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
166 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
167 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
168 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
169 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
170 // Init does not overwrite default AGC config.
171 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
172 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
173 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
174 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
175 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
176 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800177 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
178 // the tests here probe the specific set of codecs provided by the builtin
179 // factory. Those tests should probably be moved elsewhere.
180 engine_.reset(new cricket::WebRtcVoiceEngine(
181 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
182 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200183 send_parameters_.codecs.push_back(kPcmuCodec);
184 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800185 // Default Options.
186 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 }
solenberg8189b022016-06-14 12:13:00 -0700188
solenbergff976312016-03-30 23:28:51 -0700189 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700190 EXPECT_CALL(apm_, ApplyConfig(testing::_));
191 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700192 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
193 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200194 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000195 }
solenberg8189b022016-06-14 12:13:00 -0700196
solenbergff976312016-03-30 23:28:51 -0700197 bool SetupRecvStream() {
198 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700199 return false;
200 }
solenberg2100c0b2017-03-01 11:29:29 -0800201 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700202 }
solenberg8189b022016-06-14 12:13:00 -0700203
solenbergff976312016-03-30 23:28:51 -0700204 bool SetupSendStream() {
205 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000206 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 }
solenberg2100c0b2017-03-01 11:29:29 -0800208 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800209 return false;
210 }
solenberg059fb442016-10-26 05:12:24 -0700211 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800212 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 }
solenberg8189b022016-06-14 12:13:00 -0700214
215 bool AddRecvStream(uint32_t ssrc) {
216 EXPECT_TRUE(channel_);
217 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
218 }
219
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000220 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700221 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700222 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800223 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
224 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700225 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800226 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000227 }
solenberg8189b022016-06-14 12:13:00 -0700228
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700230 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000231 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200234 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
237
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100238 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
239 const auto* send_stream = call_.GetAudioSendStream(ssrc);
240 EXPECT_TRUE(send_stream);
241 return *send_stream;
242 }
243
deadbeef884f5852016-01-15 09:20:04 -0800244 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
245 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
246 EXPECT_TRUE(recv_stream);
247 return *recv_stream;
248 }
249
solenberg3a941542015-11-16 07:34:50 -0800250 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800251 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800252 }
253
solenberg7add0582015-11-20 09:59:34 -0800254 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800255 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800256 }
257
solenberg059fb442016-10-26 05:12:24 -0700258 void SetSend(bool enable) {
259 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700260 if (enable) {
261 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
262 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
263 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700264 EXPECT_CALL(apm_, ApplyConfig(testing::_));
265 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700266 }
solenberg059fb442016-10-26 05:12:24 -0700267 channel_->SetSend(enable);
268 }
269
270 void SetSendParameters(const cricket::AudioSendParameters& params) {
271 EXPECT_CALL(apm_, ApplyConfig(testing::_));
272 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
273 ASSERT_TRUE(channel_);
274 EXPECT_TRUE(channel_->SetSendParameters(params));
275 }
276
minyue6b825df2016-10-31 04:08:32 -0700277 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
278 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700279 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
280 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700281 if (enable && options) {
282 EXPECT_CALL(apm_, ApplyConfig(testing::_));
283 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
284 }
285 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700286 }
287
solenbergffbbcac2016-11-17 05:25:37 -0800288 void TestInsertDtmf(uint32_t ssrc, bool caller,
289 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700290 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000291 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700292 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000293 // send stream.
294 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800295 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000296 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000297
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700299 SetSendParameters(send_parameters_);
300 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800302 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800303 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700304 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306
307 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700308 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800309 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800311 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 }
313
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800315 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100317 // Test send.
318 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800319 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100320 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800322 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800323 EXPECT_EQ(codec.id, telephone_event.payload_type);
324 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100325 EXPECT_EQ(2, telephone_event.event_code);
326 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 }
328
329 // Test that send bandwidth is set correctly.
330 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000331 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
332 // |expected_result| is the expected result from SetMaxSendBandwidth().
333 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700334 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
335 int max_bitrate,
336 bool expected_result,
337 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200338 cricket::AudioSendParameters parameters;
339 parameters.codecs.push_back(codec);
340 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700341 if (expected_result) {
342 SetSendParameters(parameters);
343 } else {
344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
345 }
solenberg2100c0b2017-03-01 11:29:29 -0800346 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 }
348
skvlade0d46372016-04-07 22:59:22 -0700349 // Sets the per-stream maximum bitrate limit for the specified SSRC.
350 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700351 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700352 EXPECT_EQ(1UL, parameters.encodings.size());
353
deadbeefe702b302017-02-04 12:09:01 -0800354 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700355 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700356 }
357
solenberg059fb442016-10-26 05:12:24 -0700358 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700359 cricket::AudioSendParameters send_parameters;
360 send_parameters.codecs.push_back(codec);
361 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700362 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700363 }
364
minyue7a973442016-10-20 03:27:12 -0700365 void CheckSendCodec(int32_t ssrc,
366 const char expected_name[],
367 int expected_channels,
368 int expected_bitrate) {
369 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
370 EXPECT_STREQ(expected_name, codec.plname);
371 EXPECT_EQ(expected_channels, codec.channels);
372 EXPECT_EQ(expected_bitrate, codec.rate);
373 }
374
375 int GetOpusMaxPlaybackRate(int32_t ssrc) {
376 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
377 }
378
379 bool GetOpusDtx(int32_t ssrc) {
380 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
381 }
382
383 bool GetCodecFec(int32_t ssrc) {
384 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
385 }
386
skvlade0d46372016-04-07 22:59:22 -0700387 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700388 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
389 }
390
391 int GetCodecPacSize(int32_t ssrc) {
392 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
minyue6b825df2016-10-31 04:08:32 -0700395 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
396 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
397 }
398
skvlade0d46372016-04-07 22:59:22 -0700399 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
400 int global_max,
401 int stream_max,
402 bool expected_result,
403 int expected_codec_bitrate) {
404 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800405 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700406
407 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700408 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800409 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700410
411 // Verify that reading back the parameters gives results
412 // consistent with the Set() result.
413 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800414 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700415 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
416 EXPECT_EQ(expected_result ? stream_max : -1,
417 resulting_parameters.encodings[0].max_bitrate_bps);
418
419 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800420 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700421 }
422
stefan13f1a0a2016-11-30 07:22:58 -0800423 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
424 int expected_min_bitrate_bps,
425 const char* start_bitrate_kbps,
426 int expected_start_bitrate_bps,
427 const char* max_bitrate_kbps,
428 int expected_max_bitrate_bps) {
429 EXPECT_TRUE(SetupSendStream());
430 auto& codecs = send_parameters_.codecs;
431 codecs.clear();
432 codecs.push_back(kOpusCodec);
433 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
436 SetSendParameters(send_parameters_);
437
438 EXPECT_EQ(expected_min_bitrate_bps,
439 call_.GetConfig().bitrate_config.min_bitrate_bps);
440 EXPECT_EQ(expected_start_bitrate_bps,
441 call_.GetConfig().bitrate_config.start_bitrate_bps);
442 EXPECT_EQ(expected_max_bitrate_bps,
443 call_.GetConfig().bitrate_config.max_bitrate_bps);
444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800536 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
541 stats.aec_quality_min = 9.01f;
542 stats.echo_delay_median_ms = 234;
543 stats.echo_delay_std_ms = 567;
544 stats.echo_return_loss = 890;
545 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700546 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800547 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700548 stats.typing_noise_detected = true;
549 return stats;
550 }
551 void SetAudioSendStreamStats() {
552 for (auto* s : call_.GetAudioSendStreams()) {
553 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200554 }
solenberg85a04962015-10-27 03:35:21 -0700555 }
solenberg566ef242015-11-06 15:34:49 -0800556 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
557 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700558 const auto stats = GetAudioSendStreamStats();
559 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
560 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
561 EXPECT_EQ(info.packets_sent, stats.packets_sent);
562 EXPECT_EQ(info.packets_lost, stats.packets_lost);
563 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
564 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800565 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700566 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
567 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
568 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
569 EXPECT_EQ(info.audio_level, stats.audio_level);
570 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
571 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
572 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
573 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
574 EXPECT_EQ(info.echo_return_loss_enhancement,
575 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700576 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800577 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
578 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800579 EXPECT_EQ(info.typing_noise_detected,
580 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700581 }
582
583 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
584 webrtc::AudioReceiveStream::Stats stats;
585 stats.remote_ssrc = 123;
586 stats.bytes_rcvd = 456;
587 stats.packets_rcvd = 768;
588 stats.packets_lost = 101;
589 stats.fraction_lost = 23.45f;
590 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800591 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700592 stats.ext_seqnum = 678;
593 stats.jitter_ms = 901;
594 stats.jitter_buffer_ms = 234;
595 stats.jitter_buffer_preferred_ms = 567;
596 stats.delay_estimate_ms = 890;
597 stats.audio_level = 1234;
598 stats.expand_rate = 5.67f;
599 stats.speech_expand_rate = 8.90f;
600 stats.secondary_decoded_rate = 1.23f;
601 stats.accelerate_rate = 4.56f;
602 stats.preemptive_expand_rate = 7.89f;
603 stats.decoding_calls_to_silence_generator = 12;
604 stats.decoding_calls_to_neteq = 345;
605 stats.decoding_normal = 67890;
606 stats.decoding_plc = 1234;
607 stats.decoding_cng = 5678;
608 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700609 stats.decoding_muted_output = 3456;
610 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200611 return stats;
612 }
613 void SetAudioReceiveStreamStats() {
614 for (auto* s : call_.GetAudioReceiveStreams()) {
615 s->SetStats(GetAudioReceiveStreamStats());
616 }
617 }
618 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700619 const auto stats = GetAudioReceiveStreamStats();
620 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
621 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
622 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
623 EXPECT_EQ(info.packets_lost, stats.packets_lost);
624 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
625 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800626 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700627 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
628 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
629 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200630 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700631 stats.jitter_buffer_preferred_ms);
632 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
633 EXPECT_EQ(info.audio_level, stats.audio_level);
634 EXPECT_EQ(info.expand_rate, stats.expand_rate);
635 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
636 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
637 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
638 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700640 stats.decoding_calls_to_silence_generator);
641 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
642 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
643 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
644 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
645 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700646 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200648 }
hbos1acfbd22016-11-17 23:43:29 -0800649 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
650 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
651 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
652 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
653 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
654 codec.ToCodecParameters());
655 }
656 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
657 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
658 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
659 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
660 codec.ToCodecParameters());
661 }
662 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200663
peah8271d042016-11-22 07:24:52 -0800664 bool IsHighPassFilterEnabled() {
665 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
666 }
667
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700669 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700670 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800671 webrtc::test::MockGainControl& apm_gc_;
672 webrtc::test::MockEchoCancellation& apm_ec_;
673 webrtc::test::MockNoiseSuppression& apm_ns_;
674 webrtc::test::MockVoiceDetection& apm_vd_;
675 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700676 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200677 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700679 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700680 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200681 cricket::AudioSendParameters send_parameters_;
682 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800683 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800684 private:
685 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686};
687
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688// Tests that we can create and destroy a channel.
689TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700690 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691}
692
solenberg31fec402016-05-06 02:13:12 -0700693// Test that we can add a send stream and that it has the correct defaults.
694TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
695 EXPECT_TRUE(SetupChannel());
696 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800697 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
698 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
699 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700700 EXPECT_EQ("", config.rtp.c_name);
701 EXPECT_EQ(0u, config.rtp.extensions.size());
702 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
703 config.send_transport);
704}
705
706// Test that we can add a receive stream and that it has the correct defaults.
707TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
708 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800709 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700710 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800711 GetRecvStreamConfig(kSsrcX);
712 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700713 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
714 EXPECT_FALSE(config.rtp.transport_cc);
715 EXPECT_EQ(0u, config.rtp.extensions.size());
716 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
717 config.rtcp_send_transport);
718 EXPECT_EQ("", config.sync_group);
719}
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700722// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700723// TODO(ossu): This test should move into a separate builtin audio codecs
724// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700725TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700726 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 ASSERT_FALSE(codecs.empty());
728 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
729 EXPECT_EQ(48000, codecs[0].clockrate);
730 EXPECT_EQ(2, codecs[0].channels);
731 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732}
733
stefanba4c0e42016-02-04 04:12:24 -0800734TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700735 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800736 bool opus_found = false;
737 for (cricket::AudioCodec codec : codecs) {
738 if (codec.name == "opus") {
739 EXPECT_TRUE(HasTransportCc(codec));
740 opus_found = true;
741 }
742 }
743 EXPECT_TRUE(opus_found);
744}
745
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746// Tests that we can find codecs by name or id, and that we interpret the
747// clockrate and bitrate fields properly.
748TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
749 cricket::AudioCodec codec;
750 webrtc::CodecInst codec_inst;
751 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800752 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000753 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800754 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800756 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
757 &codec_inst));
758 // Find telephone-event with explicit clockrate and 0 bitrate.
759 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800760 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 // Find ISAC with a different payload id.
762 codec = kIsacCodec;
763 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800764 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 EXPECT_EQ(codec.id, codec_inst.pltype);
766 // Find PCMU with a 0 clockrate.
767 codec = kPcmuCodec;
768 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800769 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 EXPECT_EQ(codec.id, codec_inst.pltype);
771 EXPECT_EQ(8000, codec_inst.plfreq);
772 // Find PCMU with a 0 bitrate.
773 codec = kPcmuCodec;
774 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800775 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 EXPECT_EQ(codec.id, codec_inst.pltype);
777 EXPECT_EQ(64000, codec_inst.rate);
778 // Find ISAC with an explicit bitrate.
779 codec = kIsacCodec;
780 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800781 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 EXPECT_EQ(codec.id, codec_inst.pltype);
783 EXPECT_EQ(32000, codec_inst.rate);
784}
785
786// Test that we set our inbound codecs properly, including changing PT.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
791 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800792 parameters.codecs.push_back(kTelephoneEventCodec1);
793 parameters.codecs.push_back(kTelephoneEventCodec2);
794 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 parameters.codecs[2].id = 126;
796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg670a7f32017-03-24 05:56:21 -0700798 int channel_num = voe_.GetLastChannel();
799
800 webrtc::CodecInst gcodec;
801 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
802 gcodec.plfreq = 16000;
803 gcodec.channels = 1;
804 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
805 EXPECT_EQ(106, gcodec.pltype);
806 EXPECT_STREQ("ISAC", gcodec.plname);
807
808 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
809 gcodec.plfreq = 8000;
810 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
811 EXPECT_EQ(126, gcodec.pltype);
812 EXPECT_STREQ("telephone-event", gcodec.plname);
813
814 gcodec.plfreq = 32000;
815 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
816 EXPECT_EQ(107, gcodec.pltype);
817 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818}
819
820// Test that we fail to set an unknown inbound codec.
821TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700822 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200823 cricket::AudioRecvParameters parameters;
824 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700825 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827}
828
829// Test that we fail if we have duplicate types in the inbound list.
830TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200832 cricket::AudioRecvParameters parameters;
833 parameters.codecs.push_back(kIsacCodec);
834 parameters.codecs.push_back(kCn16000Codec);
835 parameters.codecs[1].id = kIsacCodec.id;
836 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839// Test that we can decode OPUS without stereo parameters.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
844 parameters.codecs.push_back(kPcmuCodec);
845 parameters.codecs.push_back(kOpusCodec);
846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800847 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg670a7f32017-03-24 05:56:21 -0700848 int channel_num = voe_.GetLastChannel();
849 webrtc::CodecInst opus;
850 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
851 // Even without stereo parameters, recv codecs still specify channels = 2.
852 EXPECT_EQ(2, opus.channels);
853 EXPECT_EQ(111, opus.pltype);
854 EXPECT_STREQ("opus", opus.plname);
855 opus.pltype = 0;
856 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
857 EXPECT_EQ(111, opus.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we can decode OPUS with stereo = 0.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
866 parameters.codecs.push_back(kOpusCodec);
867 parameters.codecs[2].params["stereo"] = "0";
868 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800869 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg670a7f32017-03-24 05:56:21 -0700870 int channel_num2 = voe_.GetLastChannel();
871 webrtc::CodecInst opus;
872 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
873 // Even when stereo is off, recv codecs still specify channels = 2.
874 EXPECT_EQ(2, opus.channels);
875 EXPECT_EQ(111, opus.pltype);
876 EXPECT_STREQ("opus", opus.plname);
877 opus.pltype = 0;
878 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
879 EXPECT_EQ(111, opus.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882// Test that we can decode OPUS with stereo = 1.
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
887 parameters.codecs.push_back(kPcmuCodec);
888 parameters.codecs.push_back(kOpusCodec);
889 parameters.codecs[2].params["stereo"] = "1";
890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800891 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg670a7f32017-03-24 05:56:21 -0700892 int channel_num2 = voe_.GetLastChannel();
893 webrtc::CodecInst opus;
894 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
895 EXPECT_EQ(2, opus.channels);
896 EXPECT_EQ(111, opus.pltype);
897 EXPECT_STREQ("opus", opus.plname);
898 opus.pltype = 0;
899 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
900 EXPECT_EQ(111, opus.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
903// Test that changes to recv codecs are applied to all streams.
904TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700905 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200906 cricket::AudioRecvParameters parameters;
907 parameters.codecs.push_back(kIsacCodec);
908 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800909 parameters.codecs.push_back(kTelephoneEventCodec1);
910 parameters.codecs.push_back(kTelephoneEventCodec2);
911 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 parameters.codecs[2].id = 126;
913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg670a7f32017-03-24 05:56:21 -0700914 EXPECT_TRUE(AddRecvStream(kSsrcX));
915 int channel_num2 = voe_.GetLastChannel();
916
917 webrtc::CodecInst gcodec;
918 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
919 gcodec.plfreq = 16000;
920 gcodec.channels = 1;
921 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
922 EXPECT_EQ(106, gcodec.pltype);
923 EXPECT_STREQ("ISAC", gcodec.plname);
924
925 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
926 gcodec.plfreq = 8000;
927 gcodec.channels = 1;
928 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
929 EXPECT_EQ(126, gcodec.pltype);
930 EXPECT_STREQ("telephone-event", gcodec.plname);
931
932 gcodec.plfreq = 32000;
933 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
934 EXPECT_EQ(107, gcodec.pltype);
935 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936}
937
938TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200940 cricket::AudioRecvParameters parameters;
941 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800942 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200943 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
solenberg2100c0b2017-03-01 11:29:29 -0800945 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800946 ASSERT_EQ(1, dm.count(106));
947 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948}
949
950// Test that we can apply the same set of codecs again while playing.
951TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200953 cricket::AudioRecvParameters parameters;
954 parameters.codecs.push_back(kIsacCodec);
955 parameters.codecs.push_back(kCn16000Codec);
956 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700957 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200958 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959
960 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200961 parameters.codecs[0].id = 127;
962 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800963 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
966// Test that we can add a codec while playing.
967TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200969 cricket::AudioRecvParameters parameters;
970 parameters.codecs.push_back(kIsacCodec);
971 parameters.codecs.push_back(kCn16000Codec);
972 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700973 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 parameters.codecs.push_back(kOpusCodec);
976 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800977 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800979 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
981}
982
983TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700984 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000986 // Test that when autobw is enabled, bitrate is kept as the default
987 // value. autobw is enabled for the following tests because the target
988 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989
990 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700991 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992
993 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700994 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700997 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998}
999
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001000TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001001 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001003 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
1007 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1008 // Rates above the max (56000) should be capped.
1009 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001012 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1013 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1014 // Rates above the max (510000) should be capped.
1015 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016}
1017
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001018TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001019 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001020
1021 // Test that we can only set a maximum bitrate for a fixed-rate codec
1022 // if it's bigger than the fixed rate.
1023
1024 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001025 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1026 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1027 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1028 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1029 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1030 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1031 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001032}
1033
1034TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001035 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001036 const int kDesiredBitrate = 128000;
1037 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001038 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001039 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001040 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001041
1042 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001043 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001044
solenberg2100c0b2017-03-01 11:29:29 -08001045 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001046}
1047
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001048// Test that bitrate cannot be set for CBR codecs.
1049// Bitrate is ignored if it is higher than the fixed bitrate.
1050// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001051TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001052 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053
1054 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001055 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001056 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001057
1058 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001059 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001060 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001061
1062 send_parameters_.max_bandwidth_bps = 128;
1063 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065}
1066
skvlade0d46372016-04-07 22:59:22 -07001067// Test that the per-stream bitrate limit and the global
1068// bitrate limit both apply.
1069TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1070 EXPECT_TRUE(SetupSendStream());
1071
1072 // opus, default bitrate == 64000.
1073 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1074 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1075 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1076 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1077
1078 // CBR codecs allow both maximums to exceed the bitrate.
1079 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1080 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1081 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1082 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1083
1084 // CBR codecs don't allow per stream maximums to be too low.
1085 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1086 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1087}
1088
1089// Test that an attempt to set RtpParameters for a stream that does not exist
1090// fails.
1091TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1092 EXPECT_TRUE(SetupChannel());
1093 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001094 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001095 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1096
1097 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001098 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001099}
1100
1101TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001102 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001103 // This test verifies that setting RtpParameters succeeds only if
1104 // the structure contains exactly one encoding.
1105 // TODO(skvlad): Update this test when we start supporting setting parameters
1106 // for each encoding individually.
1107
1108 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001109 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001110 // Two or more encodings should result in failure.
1111 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001112 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001113 // Zero encodings should also fail.
1114 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001115 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001116}
1117
1118// Changing the SSRC through RtpParameters is not allowed.
1119TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1120 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001122 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001123 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001124}
1125
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001126// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001128TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1129 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001130 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001131 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001132 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001134 ASSERT_EQ(1u, parameters.encodings.size());
1135 ASSERT_TRUE(parameters.encodings[0].active);
1136 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001137 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1138 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139
1140 // Now change it back to active and verify we resume sending.
1141 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001142 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1143 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144}
1145
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001146// Test that SetRtpSendParameters configures the correct encoding channel for
1147// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001148TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1149 SetupForMultiSendStream();
1150 // Create send streams.
1151 for (uint32_t ssrc : kSsrcs4) {
1152 EXPECT_TRUE(
1153 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1154 }
1155 // Configure one stream to be limited by the stream config, another to be
1156 // limited by the global max, and the third one with no per-stream limit
1157 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001158 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001159 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1160 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1161 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1162
1163 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1164 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1165 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1166
1167 // Remove the global cap; the streams should switch to their respective
1168 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001169 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001170 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1171 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1172 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1173}
1174
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001175// Test that GetRtpSendParameters returns the currently configured codecs.
1176TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001177 EXPECT_TRUE(SetupSendStream());
1178 cricket::AudioSendParameters parameters;
1179 parameters.codecs.push_back(kIsacCodec);
1180 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001181 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001182
solenberg2100c0b2017-03-01 11:29:29 -08001183 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001184 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001185 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1186 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001187}
1188
deadbeefcb443432016-12-12 11:12:36 -08001189// Test that GetRtpSendParameters returns an SSRC.
1190TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1191 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001192 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001193 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001194 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001195}
1196
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001197// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001198TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001199 EXPECT_TRUE(SetupSendStream());
1200 cricket::AudioSendParameters parameters;
1201 parameters.codecs.push_back(kIsacCodec);
1202 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001203 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001204
solenberg2100c0b2017-03-01 11:29:29 -08001205 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001206
1207 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001208 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001209
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001211 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1212 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213}
1214
1215// Test that GetRtpReceiveParameters returns the currently configured codecs.
1216TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1217 EXPECT_TRUE(SetupRecvStream());
1218 cricket::AudioRecvParameters parameters;
1219 parameters.codecs.push_back(kIsacCodec);
1220 parameters.codecs.push_back(kPcmuCodec);
1221 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1222
1223 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001224 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1226 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1227 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1228}
1229
deadbeefcb443432016-12-12 11:12:36 -08001230// Test that GetRtpReceiveParameters returns an SSRC.
1231TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1232 EXPECT_TRUE(SetupRecvStream());
1233 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001234 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001235 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001236 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001237}
1238
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001239// Test that if we set/get parameters multiple times, we get the same results.
1240TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1241 EXPECT_TRUE(SetupRecvStream());
1242 cricket::AudioRecvParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
1245 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1246
1247 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001248 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001249
1250 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001251 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252
1253 // ... And this shouldn't change the params returned by
1254 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001255 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1256 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257}
1258
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001259// Test that we apply codecs properly.
1260TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001261 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001262 cricket::AudioSendParameters parameters;
1263 parameters.codecs.push_back(kIsacCodec);
1264 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001265 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001266 parameters.codecs[0].id = 96;
1267 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001268 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001269 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001270 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001271 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001272 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1273 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1274 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1275 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001276 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001277 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278}
1279
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001280// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1281// to apply.
1282TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001283 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001284 cricket::AudioSendParameters parameters;
1285 parameters.codecs.push_back(kIsacCodec);
1286 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001287 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001288 parameters.codecs[0].id = 96;
1289 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001290 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001291 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001292 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001293 // Calling SetSendCodec again with same codec which is already set.
1294 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001295 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001296 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001297}
1298
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001299// Verify that G722 is set with 16000 samples per second to WebRTC.
1300TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001301 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001302 cricket::AudioSendParameters parameters;
1303 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001304 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001305 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001306 EXPECT_STREQ("G722", gcodec.plname);
1307 EXPECT_EQ(1, gcodec.channels);
1308 EXPECT_EQ(16000, gcodec.plfreq);
1309}
1310
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001311// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001313 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001314 cricket::AudioSendParameters parameters;
1315 parameters.codecs.push_back(kOpusCodec);
1316 parameters.codecs[0].bitrate = 0;
1317 parameters.codecs[0].clockrate = 50000;
1318 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319}
1320
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001321// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001323 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001324 cricket::AudioSendParameters parameters;
1325 parameters.codecs.push_back(kOpusCodec);
1326 parameters.codecs[0].bitrate = 0;
1327 parameters.codecs[0].channels = 0;
1328 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329}
1330
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001331// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001333 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001334 cricket::AudioSendParameters parameters;
1335 parameters.codecs.push_back(kOpusCodec);
1336 parameters.codecs[0].bitrate = 0;
1337 parameters.codecs[0].channels = 0;
1338 parameters.codecs[0].params["stereo"] = "1";
1339 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340}
1341
1342// Test that if channel is 1 for opus and there's no stereo, we fail.
1343TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001344 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001345 cricket::AudioSendParameters parameters;
1346 parameters.codecs.push_back(kOpusCodec);
1347 parameters.codecs[0].bitrate = 0;
1348 parameters.codecs[0].channels = 1;
1349 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350}
1351
1352// Test that if channel is 1 for opus and stereo=0, we fail.
1353TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001354 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 cricket::AudioSendParameters parameters;
1356 parameters.codecs.push_back(kOpusCodec);
1357 parameters.codecs[0].bitrate = 0;
1358 parameters.codecs[0].channels = 1;
1359 parameters.codecs[0].params["stereo"] = "0";
1360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361}
1362
1363// Test that if channel is 1 for opus and stereo=1, we fail.
1364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kOpusCodec);
1368 parameters.codecs[0].bitrate = 0;
1369 parameters.codecs[0].channels = 1;
1370 parameters.codecs[0].params["stereo"] = "1";
1371 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372}
1373
1374// Test that with bitrate=0 and no stereo,
1375// channels and bitrate are 1 and 32000.
1376TEST_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);
solenberg2100c0b2017-03-01 11:29:29 -08001382 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383}
1384
1385// Test that with bitrate=0 and stereo=0,
1386// channels and bitrate are 1 and 32000.
1387TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kOpusCodec);
1391 parameters.codecs[0].bitrate = 0;
1392 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001394 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397// Test that with bitrate=invalid and stereo=0,
1398// channels and bitrate are 1 and 32000.
1399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001404 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001407 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001408
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001410 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001411 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001412}
1413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414// Test that with bitrate=0 and stereo=1,
1415// channels and bitrate are 2 and 64000.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 0;
1421 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001422 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001423 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424}
1425
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001426// Test that with bitrate=invalid and stereo=1,
1427// channels and bitrate are 2 and 64000.
1428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001433 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001434 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001435 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001436 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001440 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001441}
1442
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443// Test that with bitrate=N and stereo unset,
1444// channels and bitrate are 1 and N.
1445TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001446 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 cricket::AudioSendParameters parameters;
1448 parameters.codecs.push_back(kOpusCodec);
1449 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001451 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452 EXPECT_EQ(111, gcodec.pltype);
1453 EXPECT_EQ(96000, gcodec.rate);
1454 EXPECT_STREQ("opus", gcodec.plname);
1455 EXPECT_EQ(1, gcodec.channels);
1456 EXPECT_EQ(48000, gcodec.plfreq);
1457}
1458
1459// Test that with bitrate=N and stereo=0,
1460// channels and bitrate are 1 and N.
1461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].bitrate = 30000;
1466 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001467 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001468 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469}
1470
1471// Test that with bitrate=N and without any parameters,
1472// channels and bitrate are 1 and N.
1473TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001474 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001475 cricket::AudioSendParameters parameters;
1476 parameters.codecs.push_back(kOpusCodec);
1477 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001478 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001479 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480}
1481
1482// Test that with bitrate=N and stereo=1,
1483// channels and bitrate are 2 and N.
1484TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001485 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001486 cricket::AudioSendParameters parameters;
1487 parameters.codecs.push_back(kOpusCodec);
1488 parameters.codecs[0].bitrate = 30000;
1489 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001490 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001491 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001492}
1493
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001494// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1495// Also test that the "maxaveragebitrate" can't be set to values outside the
1496// range of 6000 and 510000
1497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001502 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001504 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001505 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001506
1507 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001508 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001509 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001510 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001511
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001512 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001513 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001514 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001515}
1516
stefan13f1a0a2016-11-30 07:22:58 -08001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1518 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1519 200000);
1520}
1521
1522TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1523 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1524}
1525
1526TEST_F(WebRtcVoiceEngineTestFake,
1527 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1528 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1529}
1530
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1532 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1533}
1534
1535TEST_F(WebRtcVoiceEngineTestFake,
1536 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1537 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1538 200000);
1539 send_parameters_.max_bandwidth_bps = 300000;
1540 SetSendParameters(send_parameters_);
1541 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1542 << "Setting max bitrate should keep previous min bitrate.";
1543 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1544 << "Setting max bitrate should not reset start bitrate.";
1545 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1546}
1547
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001548// Test that we can enable NACK with opus as caller.
1549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001550 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].AddFeedbackParam(
1554 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1555 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001558 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001561// Test that we can enable NACK with opus as callee.
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].AddFeedbackParam(
1567 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1568 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001569 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001570 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001571 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001573
1574 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001575 cricket::StreamParams::CreateLegacy(kSsrcX)));
1576 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001577}
1578
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579// Test that we can enable NACK on receive streams.
1580TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001581 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].AddFeedbackParam(
1586 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1587 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1589 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
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}
1594
1595// Test that we can disable NACK.
1596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].AddFeedbackParam(
1601 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1602 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001605
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 parameters.codecs.clear();
1607 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001608 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610}
1611
1612// Test that we can disable NACK on receive streams.
1613TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001614 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
1618 parameters.codecs[0].AddFeedbackParam(
1619 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1620 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1623 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 parameters.codecs.clear();
1626 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001627 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1629 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001630}
1631
1632// Test that NACK is enabled on a new receive stream.
1633TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001634 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kIsacCodec);
1637 parameters.codecs.push_back(kCn16000Codec);
1638 parameters.codecs[0].AddFeedbackParam(
1639 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1640 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643
solenberg2100c0b2017-03-01 11:29:29 -08001644 EXPECT_TRUE(AddRecvStream(kSsrcY));
1645 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1646 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1647 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648}
1649
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001650// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001652 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 cricket::AudioSendParameters parameters;
1654 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001655 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001656 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001657}
1658
1659// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 cricket::AudioSendParameters parameters;
1663 parameters.codecs.push_back(kOpusCodec);
1664 parameters.codecs[0].bitrate = 0;
1665 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001666 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001667 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001668}
1669
1670// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001671TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001672 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001673 cricket::AudioSendParameters parameters;
1674 parameters.codecs.push_back(kOpusCodec);
1675 parameters.codecs[0].bitrate = 0;
1676 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_TRUE(GetCodecFec(kSsrcX));
1679 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001680}
1681
1682// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001683TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001684 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 cricket::AudioSendParameters parameters;
1686 parameters.codecs.push_back(kOpusCodec);
1687 parameters.codecs[0].bitrate = 0;
1688 parameters.codecs[0].params["stereo"] = "1";
1689 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001691 EXPECT_TRUE(GetCodecFec(kSsrcX));
1692 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001693}
1694
1695// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001696TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001697 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001698 cricket::AudioSendParameters parameters;
1699 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001700 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001701 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001702}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001703
1704// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1705TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001706 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001707 cricket::AudioSendParameters parameters;
1708 parameters.codecs.push_back(kIsacCodec);
1709 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001711 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001712}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001713
1714// Test that Opus FEC status can be changed.
1715TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001716 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 cricket::AudioSendParameters parameters;
1718 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001720 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001721
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001722 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001724 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001725}
1726
stefanba4c0e42016-02-04 04:12:24 -08001727TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001729 cricket::AudioSendParameters send_parameters;
1730 send_parameters.codecs.push_back(kOpusCodec);
1731 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001733
1734 cricket::AudioRecvParameters recv_parameters;
1735 recv_parameters.codecs.push_back(kIsacCodec);
1736 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001737 EXPECT_TRUE(AddRecvStream(kSsrcX));
1738 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001739 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001740 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001741
ossudedfd282016-06-14 07:12:39 -07001742 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001744 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001745 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001746 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001747}
1748
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001749// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1750TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001751 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001752 cricket::AudioSendParameters parameters;
1753 parameters.codecs.push_back(kOpusCodec);
1754 parameters.codecs[0].bitrate = 0;
1755 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001756 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001757 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1758 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001759
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001761 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001762 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001763}
1764
1765// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1766TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 cricket::AudioSendParameters parameters;
1769 parameters.codecs.push_back(kOpusCodec);
1770 parameters.codecs[0].bitrate = 0;
1771 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001772 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001773 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1774 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001775
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001778 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001779}
1780
1781// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1782TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001783 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 cricket::AudioSendParameters parameters;
1785 parameters.codecs.push_back(kOpusCodec);
1786 parameters.codecs[0].bitrate = 0;
1787 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001788 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001789 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1790 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001791
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001792 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001794 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001795}
1796
1797// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1798TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001799 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 cricket::AudioSendParameters parameters;
1801 parameters.codecs.push_back(kOpusCodec);
1802 parameters.codecs[0].bitrate = 0;
1803 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001804 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001805 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1806 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001807
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001808 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001809 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001810 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001811}
1812
1813// Test 24000 < maxplaybackrate triggers Opus full band mode.
1814TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001815 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 cricket::AudioSendParameters parameters;
1817 parameters.codecs.push_back(kOpusCodec);
1818 parameters.codecs[0].bitrate = 0;
1819 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001821 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1822 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001823
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001826 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001827}
1828
1829// Test Opus that without maxplaybackrate, default playback rate is used.
1830TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001831 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001832 cricket::AudioSendParameters parameters;
1833 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001834 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001835 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001836}
1837
1838// Test the with non-Opus, maxplaybackrate has no effect.
1839TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001840 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 cricket::AudioSendParameters parameters;
1842 parameters.codecs.push_back(kIsacCodec);
1843 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001845 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001846}
1847
1848// Test maxplaybackrate can be set on two streams.
1849TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001850 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001851 cricket::AudioSendParameters parameters;
1852 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001854 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001855
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001856 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001857 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001858 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001859
solenberg2100c0b2017-03-01 11:29:29 -08001860 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1861 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001862}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001863
Minyue Li7100dcd2015-03-27 05:05:59 +01001864// Test that with usedtx=0, Opus DTX is off.
1865TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001866 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001867 cricket::AudioSendParameters parameters;
1868 parameters.codecs.push_back(kOpusCodec);
1869 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001870 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001871 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001872}
1873
1874// Test that with usedtx=1, Opus DTX is on.
1875TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001876 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001877 cricket::AudioSendParameters parameters;
1878 parameters.codecs.push_back(kOpusCodec);
1879 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001881 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001882}
1883
1884// Test that usedtx=1 works with stereo Opus.
1885TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
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(kOpusCodec);
1889 parameters.codecs[0].params["usedtx"] = "1";
1890 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001892 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001893}
1894
1895// Test that usedtx=1 does not work with non Opus.
1896TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001897 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001898 cricket::AudioSendParameters parameters;
1899 parameters.codecs.push_back(kIsacCodec);
1900 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001901 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001902 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001903}
1904
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001905// Test that we can switch back and forth between Opus and ISAC with CN.
1906TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001907 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001908
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 cricket::AudioSendParameters opus_parameters;
1910 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001912 {
solenberg2100c0b2017-03-01 11:29:29 -08001913 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001914 EXPECT_EQ(111, gcodec.pltype);
1915 EXPECT_STREQ("opus", gcodec.plname);
1916 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 cricket::AudioSendParameters isac_parameters;
1919 isac_parameters.codecs.push_back(kIsacCodec);
1920 isac_parameters.codecs.push_back(kCn16000Codec);
1921 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001922 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001923 {
solenberg2100c0b2017-03-01 11:29:29 -08001924 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001925 EXPECT_EQ(103, gcodec.pltype);
1926 EXPECT_STREQ("ISAC", gcodec.plname);
1927 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928
solenberg059fb442016-10-26 05:12:24 -07001929 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001930 {
solenberg2100c0b2017-03-01 11:29:29 -08001931 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001932 EXPECT_EQ(111, gcodec.pltype);
1933 EXPECT_STREQ("opus", gcodec.plname);
1934 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935}
1936
1937// Test that we handle various ways of specifying bitrate.
1938TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001939 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 cricket::AudioSendParameters parameters;
1941 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001943 {
solenberg2100c0b2017-03-01 11:29:29 -08001944 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001945 EXPECT_EQ(103, gcodec.pltype);
1946 EXPECT_STREQ("ISAC", gcodec.plname);
1947 EXPECT_EQ(32000, gcodec.rate);
1948 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001952 {
solenberg2100c0b2017-03-01 11:29:29 -08001953 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001954 EXPECT_EQ(103, gcodec.pltype);
1955 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001956 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001957 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001960 {
solenberg2100c0b2017-03-01 11:29:29 -08001961 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001962 EXPECT_EQ(103, gcodec.pltype);
1963 EXPECT_STREQ("ISAC", gcodec.plname);
1964 EXPECT_EQ(28000, gcodec.rate);
1965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001968 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001969 {
solenberg2100c0b2017-03-01 11:29:29 -08001970 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001971 EXPECT_EQ(0, gcodec.pltype);
1972 EXPECT_STREQ("PCMU", gcodec.plname);
1973 EXPECT_EQ(64000, gcodec.rate);
1974 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001975
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001978 {
solenberg2100c0b2017-03-01 11:29:29 -08001979 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001980 EXPECT_EQ(0, gcodec.pltype);
1981 EXPECT_STREQ("PCMU", gcodec.plname);
1982 EXPECT_EQ(64000, gcodec.rate);
1983 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001984
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001985 parameters.codecs[0] = kOpusCodec;
1986 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001987 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001988 {
solenberg2100c0b2017-03-01 11:29:29 -08001989 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001990 EXPECT_EQ(111, gcodec.pltype);
1991 EXPECT_STREQ("opus", gcodec.plname);
1992 EXPECT_EQ(32000, gcodec.rate);
1993 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001994}
1995
Brave Yao5225dd82015-03-26 07:39:19 +08001996// Test that we could set packet size specified in kCodecParamPTime.
1997TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001998 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 cricket::AudioSendParameters parameters;
2000 parameters.codecs.push_back(kOpusCodec);
2001 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002002 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002003 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002004
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002005 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07002006 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002007 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002008
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07002010 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002011 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002012
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002013 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
2014 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002015 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002016 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002017 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08002018
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
2020 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07002021 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002022 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002023 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08002024}
2025
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002026// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002028 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002029 cricket::AudioSendParameters parameters;
2030 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002031}
2032
2033// Test that we can set send codecs even with telephone-event codec as the first
2034// one on the list.
2035TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002036 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002037 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002038 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002039 parameters.codecs.push_back(kIsacCodec);
2040 parameters.codecs.push_back(kPcmuCodec);
2041 parameters.codecs[0].id = 98; // DTMF
2042 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002043 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002044 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002045 EXPECT_EQ(96, gcodec.pltype);
2046 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002047 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002048}
2049
solenberg31642aa2016-03-14 08:00:37 -07002050// Test that payload type range is limited for telephone-event codec.
2051TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002052 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002053 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002054 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002055 parameters.codecs.push_back(kIsacCodec);
2056 parameters.codecs[0].id = 0; // DTMF
2057 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002058 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002059 EXPECT_TRUE(channel_->CanInsertDtmf());
2060 parameters.codecs[0].id = 128; // DTMF
2061 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2062 EXPECT_FALSE(channel_->CanInsertDtmf());
2063 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002064 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002065 EXPECT_TRUE(channel_->CanInsertDtmf());
2066 parameters.codecs[0].id = -1; // DTMF
2067 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2068 EXPECT_FALSE(channel_->CanInsertDtmf());
2069}
2070
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002071// Test that we can set send codecs even with CN codec as the first
2072// one on the list.
2073TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002074 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002075 cricket::AudioSendParameters parameters;
2076 parameters.codecs.push_back(kCn16000Codec);
2077 parameters.codecs.push_back(kIsacCodec);
2078 parameters.codecs.push_back(kPcmuCodec);
2079 parameters.codecs[0].id = 98; // wideband CN
2080 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002081 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002082 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002083 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2084 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2085 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2086 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002087}
2088
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002089// Test that we set VAD and DTMF types correctly as caller.
2090TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002091 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002092 cricket::AudioSendParameters parameters;
2093 parameters.codecs.push_back(kIsacCodec);
2094 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002095 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002096 parameters.codecs.push_back(kCn16000Codec);
2097 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002098 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002099 parameters.codecs[0].id = 96;
2100 parameters.codecs[2].id = 97; // wideband CN
2101 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002102 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002103 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002104 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2105 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2106 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2107 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2108 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2109 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002110 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111}
2112
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002113// Test that we set VAD and DTMF types correctly as callee.
2114TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002115 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002116 cricket::AudioSendParameters parameters;
2117 parameters.codecs.push_back(kIsacCodec);
2118 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002119 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002120 parameters.codecs.push_back(kCn16000Codec);
2121 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002122 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002123 parameters.codecs[0].id = 96;
2124 parameters.codecs[2].id = 97; // wideband CN
2125 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002126 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002127 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002128 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002129
solenberg2100c0b2017-03-01 11:29:29 -08002130 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002131 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2132 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2133 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2134 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2135 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2136 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002137 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002138}
2139
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140// Test that we only apply VAD if we have a CN codec that matches the
2141// send codec clockrate.
2142TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002143 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002144 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002146 parameters.codecs.push_back(kIsacCodec);
2147 parameters.codecs.push_back(kCn16000Codec);
2148 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002149 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002150 {
solenberg2100c0b2017-03-01 11:29:29 -08002151 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002152 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2153 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2154 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2155 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2156 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2157 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002159 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002160 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002161 {
solenberg2100c0b2017-03-01 11:29:29 -08002162 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002163 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2164 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2165 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002168 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002169 {
solenberg2100c0b2017-03-01 11:29:29 -08002170 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002171 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2172 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2173 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2174 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2175 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2176 }
Brave Yao5225dd82015-03-26 07:39:19 +08002177 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002178 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002179 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002180 {
solenberg2100c0b2017-03-01 11:29:29 -08002181 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002182 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2183 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2184 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185}
2186
2187// Test that we perform case-insensitive matching of codec names.
2188TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002189 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002190 cricket::AudioSendParameters parameters;
2191 parameters.codecs.push_back(kIsacCodec);
2192 parameters.codecs.push_back(kPcmuCodec);
2193 parameters.codecs.push_back(kCn16000Codec);
2194 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002195 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002196 parameters.codecs[0].name = "iSaC";
2197 parameters.codecs[0].id = 96;
2198 parameters.codecs[2].id = 97; // wideband CN
2199 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002200 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002201 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002202 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2203 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2204 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2205 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2206 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2207 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002208 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002209}
2210
stefanba4c0e42016-02-04 04:12:24 -08002211class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2212 public:
2213 WebRtcVoiceEngineWithSendSideBweTest()
2214 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2215};
2216
2217TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2218 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002219 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002220 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002221 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2222 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2223 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002224 extension.id);
2225 return;
2226 }
2227 }
2228 FAIL() << "Transport sequence number extension not in header-extension list.";
2229}
2230
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002231// Test support for audio level header extension.
2232TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002233 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002234}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002235TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002236 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002237}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002238
solenbergd4adce42016-11-17 06:26:52 -08002239// Test support for transport sequence number header extension.
2240TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2241 TestSetSendRtpHeaderExtensions(
2242 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002243}
solenbergd4adce42016-11-17 06:26:52 -08002244TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2245 TestSetRecvRtpHeaderExtensions(
2246 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002247}
2248
solenberg1ac56142015-10-13 03:58:19 -07002249// Test that we can create a channel and start sending on it.
2250TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002251 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002252 SetSendParameters(send_parameters_);
2253 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002254 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002255 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002256 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002257}
2258
2259// Test that a channel will send if and only if it has a source and is enabled
2260// for sending.
2261TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002262 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002263 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002264 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002265 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002266 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2267 SetAudioSend(kSsrcX, true, &fake_source_);
2268 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2269 SetAudioSend(kSsrcX, true, nullptr);
2270 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002271}
2272
solenberg94218532016-06-16 10:53:22 -07002273// Test that a channel is muted/unmuted.
2274TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2275 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002276 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002277 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2278 SetAudioSend(kSsrcX, true, nullptr);
2279 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2280 SetAudioSend(kSsrcX, false, nullptr);
2281 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002282}
2283
solenberg6d6e7c52016-04-13 09:07:30 -07002284// Test that SetSendParameters() does not alter a stream's send state.
2285TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2286 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002288
2289 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002290 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002291 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002292
2293 // Changing RTP header extensions will recreate the AudioSendStream.
2294 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002295 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002296 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002298
2299 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002300 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002301 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002302
2303 // Changing RTP header extensions will recreate the AudioSendStream.
2304 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002305 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002307}
2308
solenberg1ac56142015-10-13 03:58:19 -07002309// Test that we can create a channel and start playing out on it.
2310TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002311 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002312 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002313 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002314 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002315 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317}
2318
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002319// Test that we can add and remove send streams.
2320TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2321 SetupForMultiSendStream();
2322
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002324 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002325
solenbergc96df772015-10-21 13:01:53 -07002326 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002327 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002328 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002329 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002330 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002331 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002332 }
tfarina5237aaf2015-11-10 23:44:30 -08002333 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002334
solenbergc96df772015-10-21 13:01:53 -07002335 // Delete the send streams.
2336 for (uint32_t ssrc : kSsrcs4) {
2337 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002338 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002339 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002340 }
solenbergc96df772015-10-21 13:01:53 -07002341 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342}
2343
2344// Test SetSendCodecs correctly configure the codecs in all send streams.
2345TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2346 SetupForMultiSendStream();
2347
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002348 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002349 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002350 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002351 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002352 }
2353
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002354 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002356 parameters.codecs.push_back(kIsacCodec);
2357 parameters.codecs.push_back(kCn16000Codec);
2358 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002359 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002360
2361 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002362 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002363 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2364 const auto& send_codec_spec =
2365 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2366 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2367 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2368 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2369 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2370 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002371 }
2372
minyue7a973442016-10-20 03:27:12 -07002373 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002374 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002375 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002376 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002377 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2378 const auto& send_codec_spec =
2379 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2380 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002381 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 }
2383}
2384
2385// Test we can SetSend on all send streams correctly.
2386TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2387 SetupForMultiSendStream();
2388
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002389 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002390 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002392 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002393 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002394 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002395 }
2396
2397 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002398 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002399 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002400 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002401 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002402 }
2403
2404 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002405 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002406 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002407 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002408 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002409 }
2410}
2411
2412// Test we can set the correct statistics on all send streams.
2413TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2414 SetupForMultiSendStream();
2415
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002416 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002417 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002418 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002419 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002420 }
solenberg85a04962015-10-27 03:35:21 -07002421
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002422 // Create a receive stream to check that none of the send streams end up in
2423 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002424 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002425
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002426 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002427 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002428 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002429 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002430
solenberg85a04962015-10-27 03:35:21 -07002431 // Check stats for the added streams.
2432 {
2433 cricket::VoiceMediaInfo info;
2434 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002435
solenberg85a04962015-10-27 03:35:21 -07002436 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002437 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002438 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002439 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002440 }
hbos1acfbd22016-11-17 23:43:29 -08002441 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002442
2443 // We have added one receive stream. We should see empty stats.
2444 EXPECT_EQ(info.receivers.size(), 1u);
2445 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002446 }
solenberg1ac56142015-10-13 03:58:19 -07002447
solenberg2100c0b2017-03-01 11:29:29 -08002448 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002449 {
2450 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002451 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002452 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002453 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002454 EXPECT_EQ(0u, info.receivers.size());
2455 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002456
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002457 // Deliver a new packet - a default receive stream should be created and we
2458 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002459 {
2460 cricket::VoiceMediaInfo info;
2461 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2462 SetAudioReceiveStreamStats();
2463 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002464 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002465 EXPECT_EQ(1u, info.receivers.size());
2466 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002467 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002468 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002469}
2470
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002471// Test that we can add and remove receive streams, and do proper send/playout.
2472// We can receive on multiple streams while sending one stream.
2473TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002474 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475
solenberg1ac56142015-10-13 03:58:19 -07002476 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002477 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002478 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479
solenberg1ac56142015-10-13 03:58:19 -07002480 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002482 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484
solenberg1ac56142015-10-13 03:58:19 -07002485 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002486 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487
2488 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002489 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2490 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2491 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492
2493 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002494 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002495 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496
2497 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002498 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002499 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2500 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501
aleloi84ef6152016-08-04 05:28:21 -07002502 // Restart playout and make sure recv streams are played out.
2503 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002504 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2505 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506
aleloi84ef6152016-08-04 05:28:21 -07002507 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002508 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2509 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510}
2511
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002513// and start sending on it.
2514TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002515 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002516 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2517 EXPECT_CALL(apm_gc_,
2518 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002519 SetSendParameters(send_parameters_);
2520 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002522 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002523 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524}
2525
wu@webrtc.org97077a32013-10-25 21:18:33 +00002526TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002527 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002528 EXPECT_CALL(adm_,
2529 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002530 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2531 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002532 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2533 send_parameters_.options.tx_agc_digital_compression_gain =
2534 rtc::Optional<uint16_t>(9);
2535 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2536 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002537 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2538 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2539 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002540 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002541
2542 // Check interaction with adjust_agc_delta. Both should be respected, for
2543 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002544 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002545 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002546 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002547}
2548
wu@webrtc.org97077a32013-10-25 21:18:33 +00002549TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002550 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002551 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2552 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002553 send_parameters_.options.recording_sample_rate =
2554 rtc::Optional<uint32_t>(48000);
2555 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002556 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002557}
2558
minyue6b825df2016-10-31 04:08:32 -07002559TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2560 EXPECT_TRUE(SetupSendStream());
2561 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2562 send_parameters_.options.audio_network_adaptor_config =
2563 rtc::Optional<std::string>("1234");
2564 SetSendParameters(send_parameters_);
2565 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002566 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002567}
2568
2569TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2570 EXPECT_TRUE(SetupSendStream());
2571 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2572 send_parameters_.options.audio_network_adaptor_config =
2573 rtc::Optional<std::string>("1234");
2574 SetSendParameters(send_parameters_);
2575 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002576 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002577 const int initial_num = call_.GetNumCreatedSendStreams();
2578 cricket::AudioOptions options;
2579 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002580 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002581 // AudioSendStream expected to be recreated.
2582 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002583 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002584}
2585
2586TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2587 EXPECT_TRUE(SetupSendStream());
2588 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2589 send_parameters_.options.audio_network_adaptor_config =
2590 rtc::Optional<std::string>("1234");
2591 SetSendParameters(send_parameters_);
2592 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002593 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002594 const int initial_num = call_.GetNumCreatedSendStreams();
2595 cricket::AudioOptions options;
2596 options.audio_network_adaptor = rtc::Optional<bool>();
2597 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2598 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002599 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002600 // AudioSendStream not expected to be recreated.
2601 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2602 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002603 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002604}
2605
michaelt6672b262017-01-11 10:17:59 -08002606class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2607 : public WebRtcVoiceEngineTestFake {
2608 public:
2609 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2610 : WebRtcVoiceEngineTestFake(
2611 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2612 "Enabled/") {}
2613};
2614
2615TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2616 EXPECT_TRUE(SetupSendStream());
2617 cricket::AudioSendParameters parameters;
2618 parameters.codecs.push_back(kOpusCodec);
2619 SetSendParameters(parameters);
2620 const int initial_num = call_.GetNumCreatedSendStreams();
2621 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2622
2623 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2624 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002625 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2626 constexpr int kMinOverheadBps =
2627 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002628 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2629
2630 constexpr int kOpusMinBitrateBps = 6000;
2631 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002632 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002633 constexpr int kOpusBitrateFbBps = 32000;
2634 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002635 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002636
2637 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2638 parameters.options.audio_network_adaptor_config =
2639 rtc::Optional<std::string>("1234");
2640 SetSendParameters(parameters);
2641
ossu11bfc532017-02-16 05:37:06 -08002642 constexpr int kMinOverheadWithAnaBps =
2643 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002644 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2645
2646 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002647 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002648
2649 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002650 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002651}
2652
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002654// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002657 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002658}
2659
2660TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2661 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002662 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002663 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002664 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002665 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002666 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002667 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002668 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669
solenberg85a04962015-10-27 03:35:21 -07002670 // Check stats for the added streams.
2671 {
2672 cricket::VoiceMediaInfo info;
2673 EXPECT_EQ(true, channel_->GetStats(&info));
2674
2675 // We have added one send stream. We should see the stats we've set.
2676 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002677 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002678 // We have added one receive stream. We should see empty stats.
2679 EXPECT_EQ(info.receivers.size(), 1u);
2680 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2681 }
solenberg1ac56142015-10-13 03:58:19 -07002682
solenberg566ef242015-11-06 15:34:49 -08002683 // Start sending - this affects some reported stats.
2684 {
2685 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002686 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002687 EXPECT_EQ(true, channel_->GetStats(&info));
2688 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002689 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002690 }
2691
solenberg2100c0b2017-03-01 11:29:29 -08002692 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002693 {
2694 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002695 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002696 EXPECT_EQ(true, channel_->GetStats(&info));
2697 EXPECT_EQ(1u, info.senders.size());
2698 EXPECT_EQ(0u, info.receivers.size());
2699 }
solenberg1ac56142015-10-13 03:58:19 -07002700
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002701 // Deliver a new packet - a default receive stream should be created and we
2702 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002703 {
2704 cricket::VoiceMediaInfo info;
2705 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2706 SetAudioReceiveStreamStats();
2707 EXPECT_EQ(true, channel_->GetStats(&info));
2708 EXPECT_EQ(1u, info.senders.size());
2709 EXPECT_EQ(1u, info.receivers.size());
2710 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002711 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002712 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713}
2714
2715// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002716// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002718 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002719 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2720 EXPECT_TRUE(AddRecvStream(kSsrcY));
2721 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002722}
2723
2724// Test that the local SSRC is the same on sending and receiving channels if the
2725// receive channel is created before the send channel.
2726TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002727 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002728 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002730 cricket::StreamParams::CreateLegacy(kSsrcX)));
2731 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2732 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733}
2734
2735// Test that we can properly receive packets.
2736TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002738 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002740
2741 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2742 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002743}
2744
2745// Test that we can properly receive packets on multiple streams.
2746TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002747 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002748 const uint32_t ssrc1 = 1;
2749 const uint32_t ssrc2 = 2;
2750 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002751 EXPECT_TRUE(AddRecvStream(ssrc1));
2752 EXPECT_TRUE(AddRecvStream(ssrc2));
2753 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002755 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002756 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002758 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759 }
mflodman3d7db262016-04-29 00:57:13 -07002760
2761 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2762 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2763 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2764
2765 EXPECT_EQ(s1.received_packets(), 0);
2766 EXPECT_EQ(s2.received_packets(), 0);
2767 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002768
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002770 EXPECT_EQ(s1.received_packets(), 0);
2771 EXPECT_EQ(s2.received_packets(), 0);
2772 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002773
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002775 EXPECT_EQ(s1.received_packets(), 1);
2776 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2777 EXPECT_EQ(s2.received_packets(), 0);
2778 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002779
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002780 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002781 EXPECT_EQ(s1.received_packets(), 1);
2782 EXPECT_EQ(s2.received_packets(), 1);
2783 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2784 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002785
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002787 EXPECT_EQ(s1.received_packets(), 1);
2788 EXPECT_EQ(s2.received_packets(), 1);
2789 EXPECT_EQ(s3.received_packets(), 1);
2790 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002791
mflodman3d7db262016-04-29 00:57:13 -07002792 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2793 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2794 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795}
2796
solenberg2100c0b2017-03-01 11:29:29 -08002797// Test that receiving on an unsignaled stream works (a stream is created).
2798TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002799 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002800 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2801
solenberg7e63ef02015-11-20 00:19:43 -08002802 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002803
2804 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002805 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2806 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002807}
2808
solenberg2100c0b2017-03-01 11:29:29 -08002809// Test that receiving N unsignaled stream works (streams will be created), and
2810// that packets are forwarded to them all.
2811TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002812 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002813 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002814 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2815
solenberg2100c0b2017-03-01 11:29:29 -08002816 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002817 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002818 rtc::SetBE32(&packet[8], ssrc);
2819 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002820
solenberg2100c0b2017-03-01 11:29:29 -08002821 // Verify we have one new stream for each loop iteration.
2822 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002823 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2824 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002825 }
mflodman3d7db262016-04-29 00:57:13 -07002826
solenberg2100c0b2017-03-01 11:29:29 -08002827 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002828 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002829 rtc::SetBE32(&packet[8], ssrc);
2830 DeliverPacket(packet, sizeof(packet));
2831
solenbergebb349d2017-03-13 05:46:15 -07002832 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002833 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2834 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2835 }
2836
2837 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2838 constexpr uint32_t kAnotherSsrc = 667;
2839 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002840 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002841
2842 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002843 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002844 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002845 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002846 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2847 EXPECT_EQ(2, streams[i]->received_packets());
2848 }
2849 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2850 EXPECT_EQ(1, streams[i]->received_packets());
2851 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002852 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002853}
2854
solenberg2100c0b2017-03-01 11:29:29 -08002855// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002856// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002857TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002858 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002859 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002860 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2861
2862 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002863 const uint32_t signaled_ssrc = 1;
2864 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002865 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002866 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002867 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2868 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002869 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002870
2871 // Note that the first unknown SSRC cannot be 0, because we only support
2872 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002873 const uint32_t unsignaled_ssrc = 7011;
2874 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002875 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002876 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2877 packet, sizeof(packet)));
2878 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2879
2880 DeliverPacket(packet, sizeof(packet));
2881 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2882
2883 rtc::SetBE32(&packet[8], signaled_ssrc);
2884 DeliverPacket(packet, sizeof(packet));
2885 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2886 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002887}
2888
solenberg4904fb62017-02-17 12:01:14 -08002889// Two tests to verify that adding a receive stream with the same SSRC as a
2890// previously added unsignaled stream will only recreate underlying stream
2891// objects if the stream parameters have changed.
2892TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2893 EXPECT_TRUE(SetupChannel());
2894
2895 // Spawn unsignaled stream with SSRC=1.
2896 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2897 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2898 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2899 sizeof(kPcmuFrame)));
2900
2901 // Verify that the underlying stream object in Call is not recreated when a
2902 // stream with SSRC=1 is added.
2903 const auto& streams = call_.GetAudioReceiveStreams();
2904 EXPECT_EQ(1, streams.size());
2905 int audio_receive_stream_id = streams.front()->id();
2906 EXPECT_TRUE(AddRecvStream(1));
2907 EXPECT_EQ(1, streams.size());
2908 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2909}
2910
2911TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2912 EXPECT_TRUE(SetupChannel());
2913
2914 // Spawn unsignaled stream with SSRC=1.
2915 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2916 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2917 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2918 sizeof(kPcmuFrame)));
2919
2920 // Verify that the underlying stream object in Call *is* recreated when a
2921 // stream with SSRC=1 is added, and which has changed stream parameters.
2922 const auto& streams = call_.GetAudioReceiveStreams();
2923 EXPECT_EQ(1, streams.size());
2924 int audio_receive_stream_id = streams.front()->id();
2925 cricket::StreamParams stream_params;
2926 stream_params.ssrcs.push_back(1);
2927 stream_params.sync_label = "sync_label";
2928 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2929 EXPECT_EQ(1, streams.size());
2930 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2931}
2932
solenberg0a617e22015-10-20 15:49:38 -07002933// Test that we properly handle failures to add a receive stream.
2934TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002935 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002937 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938}
2939
solenberg0a617e22015-10-20 15:49:38 -07002940// Test that we properly handle failures to add a send stream.
2941TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002942 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002943 voe_.set_fail_create_channel(true);
2944 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2945}
2946
solenberg1ac56142015-10-13 03:58:19 -07002947// Test that AddRecvStream creates new stream.
2948TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002949 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002950 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002951 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002952 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953}
2954
2955// Test that after adding a recv stream, we do not decode more codecs than
2956// those previously passed into SetRecvCodecs.
2957TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002958 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 cricket::AudioRecvParameters parameters;
2960 parameters.codecs.push_back(kIsacCodec);
2961 parameters.codecs.push_back(kPcmuCodec);
2962 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002963 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg670a7f32017-03-24 05:56:21 -07002964 int channel_num2 = voe_.GetLastChannel();
2965 webrtc::CodecInst gcodec;
2966 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
2967 gcodec.plfreq = 48000;
2968 gcodec.channels = 2;
2969 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002970}
2971
2972// Test that we properly clean up any streams that were added, even if
2973// not explicitly removed.
2974TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002975 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002976 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002977 EXPECT_TRUE(AddRecvStream(1));
2978 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2980 delete channel_;
2981 channel_ = NULL;
2982 EXPECT_EQ(0, voe_.GetNumChannels());
2983}
2984
wu@webrtc.org78187522013-10-07 23:32:02 +00002985TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002986 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002987 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002988}
2989
2990TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002991 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002992 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002993 // Manually delete channel to simulate a failure.
2994 int channel = voe_.GetLastChannel();
2995 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2996 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002997 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002998 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002999 EXPECT_NE(channel, new_channel);
3000 // The last created channel is deleted too.
3001 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00003002}
3003
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003004// Test the InsertDtmf on default send stream as caller.
3005TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08003006 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007}
3008
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003009// Test the InsertDtmf on default send stream as callee
3010TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08003011 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003012}
3013
3014// Test the InsertDtmf on specified send stream as caller.
3015TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08003016 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003017}
3018
3019// Test the InsertDtmf on specified send stream as callee.
3020TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08003021 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022}
3023
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003025 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003026 EXPECT_CALL(adm_,
3027 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3028 EXPECT_CALL(adm_,
3029 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3030 EXPECT_CALL(adm_,
3031 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003032
solenberg246b8172015-12-08 09:50:23 -08003033 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3034 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035
solenberg246b8172015-12-08 09:50:23 -08003036 // Nothing set in AudioOptions, so everything should be as default.
3037 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003038 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003039 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003040 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3041 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003042
3043 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003044 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3045 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003046 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003047 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048
3049 // Turn echo cancellation back on, with settings, and make sure
3050 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003051 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3052 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003053 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003054 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003055
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003056 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3057 // control.
solenberg76377c52017-02-21 00:54:31 -08003058 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3059 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003060 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003061 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003062
3063 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003064 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3065 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003066 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3067 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3068 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003069 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003070
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003071 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003072 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3073 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003074 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003075 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003076
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003078 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3079 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3080 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3081 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003082 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003083 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003084
3085 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003086 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3088 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3089 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003090 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3091 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003092 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003093
3094 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003095 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3096 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3097 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3098 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3099 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3100 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3101 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003102 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3103 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3104 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3105 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003106 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003107 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003108
solenberg1ac56142015-10-13 03:58:19 -07003109 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003110 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3111 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3112 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3113 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3114 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3115 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3116 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003117 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003118}
3119
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003120TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003121 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003122 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003123 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003124 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003125 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003126 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003127 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003128 EXPECT_CALL(adm_,
3129 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3130 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3131 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3132 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3133 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003134
kwiberg686a8ef2016-02-26 03:00:35 -08003135 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003136 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003137 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003138 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003139 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003140 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003141
3142 // Have to add a stream to make SetSend work.
3143 cricket::StreamParams stream1;
3144 stream1.ssrcs.push_back(1);
3145 channel1->AddSendStream(stream1);
3146 cricket::StreamParams stream2;
3147 stream2.ssrcs.push_back(2);
3148 channel2->AddSendStream(stream2);
3149
3150 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003151 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003152 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3153 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3154 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003155 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3156 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3157 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3158 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3159 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003160 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003161 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003162 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003163 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003164
3165 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003166 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003167 parameters_options_no_ns.options.noise_suppression =
3168 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003169 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3170 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3171 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3172 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3173 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003174 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003175 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003176 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3177 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3178 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003179 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003180
3181 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003182 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003183 parameters_options_no_agc.options.auto_gain_control =
3184 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003185 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3186 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3187 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3188 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3189 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003190 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003191 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3192 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3193 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003194 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003195
solenberg76377c52017-02-21 00:54:31 -08003196 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3197 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3198 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3199 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3200 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003201 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003202
solenberg76377c52017-02-21 00:54:31 -08003203 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3204 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3205 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3206 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3207 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003208 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003209
solenberg76377c52017-02-21 00:54:31 -08003210 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3211 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3212 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3213 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3214 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003215 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003216
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003217 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003218 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3219 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003220 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003221 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003222 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003223 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003224 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3225 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3226 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3227 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3228 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003229 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003230 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3231 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3232 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003233 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003234}
3235
wu@webrtc.orgde305012013-10-31 15:40:38 +00003236// This test verifies DSCP settings are properly applied on voice media channel.
3237TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003238 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003239 cricket::FakeNetworkInterface network_interface;
3240 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003241 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003242
solenberg059fb442016-10-26 05:12:24 -07003243 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3244 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3245
solenbergbc37fc82016-04-04 09:54:44 -07003246 channel.reset(
3247 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003248 channel->SetInterface(&network_interface);
3249 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3250 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3251
3252 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003253 channel.reset(
3254 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003255 channel->SetInterface(&network_interface);
3256 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3257
3258 // Verify that setting the option to false resets the
3259 // DiffServCodePoint.
3260 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003261 channel.reset(
3262 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003263 channel->SetInterface(&network_interface);
3264 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3265 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3266
3267 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003268}
3269
solenberg1ac56142015-10-13 03:58:19 -07003270TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003271 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003272 cricket::WebRtcVoiceMediaChannel* media_channel =
3273 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003274 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003276 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3278 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3279 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003280 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003282}
3283
solenberg1ac56142015-10-13 03:58:19 -07003284TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003285 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003286 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003287 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3288 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3289 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003290 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003291 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3293 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003294 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003295 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003296 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003297 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003298}
3299
solenberg4bac9c52015-10-09 02:32:53 -07003300TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003301 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003302 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003303 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003304 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003305 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003306 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3307 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3308 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003309}
3310
solenberg2100c0b2017-03-01 11:29:29 -08003311TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003312 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003313
3314 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003315 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003316 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3317
3318 // Should remember the volume "2" which will be set on new unsignaled streams,
3319 // and also set the gain to 2 on existing unsignaled streams.
3320 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3321 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3322
3323 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3324 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3325 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3326 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3327 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3328 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3329
3330 // Setting gain with SSRC=0 should affect all unsignaled streams.
3331 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003332 if (kMaxUnsignaledRecvStreams > 1) {
3333 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3334 }
solenberg2100c0b2017-03-01 11:29:29 -08003335 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3336
3337 // Setting gain on an individual stream affects only that.
3338 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003339 if (kMaxUnsignaledRecvStreams > 1) {
3340 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3341 }
solenberg2100c0b2017-03-01 11:29:29 -08003342 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003343}
3344
pbos8fc7fa72015-07-15 08:02:58 -07003345TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003346 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003347 const std::string kSyncLabel = "AvSyncLabel";
3348
solenbergff976312016-03-30 23:28:51 -07003349 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003350 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3351 sp.sync_label = kSyncLabel;
3352 // Creating two channels to make sure that sync label is set properly for both
3353 // the default voice channel and following ones.
3354 EXPECT_TRUE(channel_->AddRecvStream(sp));
3355 sp.ssrcs[0] += 1;
3356 EXPECT_TRUE(channel_->AddRecvStream(sp));
3357
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003358 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003359 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003360 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003361 << "SyncGroup should be set based on sync_label";
3362 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003363 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003364 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003365}
3366
solenberg3a941542015-11-16 07:34:50 -08003367// TODO(solenberg): Remove, once recv streams are configured through Call.
3368// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003369TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003370 // Test that setting the header extensions results in the expected state
3371 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003372 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003373 ssrcs.push_back(223);
3374 ssrcs.push_back(224);
3375
solenbergff976312016-03-30 23:28:51 -07003376 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003377 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003378 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003379 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003380 cricket::StreamParams::CreateLegacy(ssrc)));
3381 }
3382
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003383 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003384 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003385 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003386 EXPECT_NE(nullptr, s);
3387 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3388 }
3389
3390 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003391 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003392 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003393 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003394 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003395 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003396 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003397 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003398 EXPECT_NE(nullptr, s);
3399 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003400 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3401 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003402 for (const auto& s_ext : s_exts) {
3403 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003404 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003405 }
3406 }
3407 }
3408 }
3409
3410 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003411 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003412 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003413 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003414 EXPECT_NE(nullptr, s);
3415 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3416 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003417}
3418
3419TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3420 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003421 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003422 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003423 static const unsigned char kRtcp[] = {
3424 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3425 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3428 };
jbaucheec21bd2016-03-20 06:15:43 -07003429 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003430
solenbergff976312016-03-30 23:28:51 -07003431 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003432 cricket::WebRtcVoiceMediaChannel* media_channel =
3433 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003434 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003435 EXPECT_TRUE(media_channel->AddRecvStream(
3436 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3437
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003438 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003439 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003440 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003441 EXPECT_EQ(0, s->received_packets());
3442 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3443 EXPECT_EQ(1, s->received_packets());
3444 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3445 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003446}
Minyue2013aec2015-05-13 14:14:42 +02003447
solenberg0a617e22015-10-20 15:49:38 -07003448// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003449// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003450TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003451 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003452 EXPECT_TRUE(AddRecvStream(kSsrcY));
3453 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003454 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003455 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3456 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3457 EXPECT_TRUE(AddRecvStream(kSsrcW));
3458 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003459}
3460
solenberg7602aab2016-11-14 11:30:07 -08003461TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3462 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003463 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003464 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003465 cricket::StreamParams::CreateLegacy(kSsrcY)));
3466 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3467 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3468 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003469 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003470 cricket::StreamParams::CreateLegacy(kSsrcW)));
3471 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3472 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003473}
stefan658910c2015-09-03 05:48:32 -07003474
deadbeef884f5852016-01-15 09:20:04 -08003475TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003476 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003477 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3478 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003479
3480 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003481 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3482 EXPECT_TRUE(AddRecvStream(kSsrcX));
3483 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003484
3485 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003486 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3487 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003488
3489 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003490 channel_->SetRawAudioSink(kSsrcX, nullptr);
3491 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003492}
3493
solenberg2100c0b2017-03-01 11:29:29 -08003494TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003495 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003496 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3497 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003498 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3499 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003500
3501 // Should be able to set a default sink even when no stream exists.
3502 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3503
solenberg2100c0b2017-03-01 11:29:29 -08003504 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3505 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003506 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003507 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003508
3509 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003510 channel_->SetRawAudioSink(kSsrc0, nullptr);
3511 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003512
3513 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003514 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3515 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003516
3517 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003518 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003519 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003520 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3521
3522 // Spawn another unsignaled stream - it should be assigned the default sink
3523 // and the previous unsignaled stream should lose it.
3524 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3525 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3526 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3527 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003528 if (kMaxUnsignaledRecvStreams > 1) {
3529 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3530 }
solenberg2100c0b2017-03-01 11:29:29 -08003531 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3532
3533 // Reset the default sink - the second unsignaled stream should lose it.
3534 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003535 if (kMaxUnsignaledRecvStreams > 1) {
3536 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3537 }
solenberg2100c0b2017-03-01 11:29:29 -08003538 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3539
3540 // Try setting the default sink while two streams exists.
3541 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003542 if (kMaxUnsignaledRecvStreams > 1) {
3543 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3544 }
solenberg2100c0b2017-03-01 11:29:29 -08003545 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3546
3547 // Try setting the sink for the first unsignaled stream using its known SSRC.
3548 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003549 if (kMaxUnsignaledRecvStreams > 1) {
3550 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3551 }
solenberg2100c0b2017-03-01 11:29:29 -08003552 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003553 if (kMaxUnsignaledRecvStreams > 1) {
3554 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3555 }
deadbeef884f5852016-01-15 09:20:04 -08003556}
3557
skvlad7a43d252016-03-22 15:32:27 -07003558// Test that, just like the video channel, the voice channel communicates the
3559// network state to the call.
3560TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003561 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003562
3563 EXPECT_EQ(webrtc::kNetworkUp,
3564 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3565 EXPECT_EQ(webrtc::kNetworkUp,
3566 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3567
3568 channel_->OnReadyToSend(false);
3569 EXPECT_EQ(webrtc::kNetworkDown,
3570 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3571 EXPECT_EQ(webrtc::kNetworkUp,
3572 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3573
3574 channel_->OnReadyToSend(true);
3575 EXPECT_EQ(webrtc::kNetworkUp,
3576 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3577 EXPECT_EQ(webrtc::kNetworkUp,
3578 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3579}
3580
aleloi18e0b672016-10-04 02:45:47 -07003581// Test that playout is still started after changing parameters
3582TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3583 SetupRecvStream();
3584 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003585 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003586
3587 // Changing RTP header extensions will recreate the AudioReceiveStream.
3588 cricket::AudioRecvParameters parameters;
3589 parameters.extensions.push_back(
3590 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3591 channel_->SetRecvParameters(parameters);
3592
solenberg2100c0b2017-03-01 11:29:29 -08003593 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003594}
3595
stefan658910c2015-09-03 05:48:32 -07003596// Tests that the library initializes and shuts down properly.
3597TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003598 // If the VoiceEngine wants to gather available codecs early, that's fine but
3599 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003600 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003601 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003602 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003603 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003604 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003605 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3606 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003607 EXPECT_TRUE(channel != nullptr);
3608 delete channel;
solenbergff976312016-03-30 23:28:51 -07003609}
stefan658910c2015-09-03 05:48:32 -07003610
solenbergff976312016-03-30 23:28:51 -07003611// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003612TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3613 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3614 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3615 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003616 // Return 100ms just in case this function gets called. If we don't,
3617 // we could enter a tight loop since the mock would return 0.
3618 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003619 {
ossuc54071d2016-08-17 02:45:41 -07003620 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003621 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003622 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003623 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003624 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003625 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3626 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3627 EXPECT_TRUE(channel != nullptr);
3628 delete channel;
3629 }
stefan658910c2015-09-03 05:48:32 -07003630}
3631
3632// Tests that the library is configured with the codecs we want.
3633TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003634 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3635 // module.
3636
stefan658910c2015-09-03 05:48:32 -07003637 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003638#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003639 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003640 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003641#endif
3642#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003643 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003644 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003645#endif
3646#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003649#endif
3650#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003651 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003652 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003653 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003654 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003655 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003656#endif
solenberg26c8c912015-11-27 04:00:25 -08003657 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003658 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003659 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003660 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003661 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003662 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003663 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3664 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3665 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3666 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3667 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3668 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003669 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003670 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003671 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003672 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003673 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003674 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003675 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003676 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003677 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003678 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003679 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003680 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003681 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003682 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003683 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003684 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003685 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003686 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003687 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003688 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003689 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003690 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003691 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003692
stefan658910c2015-09-03 05:48:32 -07003693 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003694 // TODO(ossu): Why are the payload types of codecs with non-static payload
3695 // type assignments checked here? It shouldn't really matter.
3696 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003697 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003698 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3699 if (codec.name == "CN" && codec.clockrate == 16000) {
3700 EXPECT_EQ(105, codec.id);
3701 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3702 EXPECT_EQ(106, codec.id);
3703 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3704 EXPECT_EQ(103, codec.id);
3705 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3706 EXPECT_EQ(104, codec.id);
3707 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3708 EXPECT_EQ(9, codec.id);
3709 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3710 EXPECT_EQ(126, codec.id);
3711 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3712 // Remove these checks once both send and receive side assigns payload types
3713 // dynamically.
3714 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3715 EXPECT_EQ(113, codec.id);
3716 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3717 EXPECT_EQ(112, codec.id);
3718 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3719 EXPECT_EQ(110, codec.id);
3720 } else if (codec.name == "opus") {
3721 EXPECT_EQ(111, codec.id);
3722 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3723 EXPECT_EQ("10", codec.params.find("minptime")->second);
3724 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3725 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003726 }
3727 }
stefan658910c2015-09-03 05:48:32 -07003728}
3729
3730// Tests that VoE supports at least 32 channels
3731TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003732 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003733 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003734 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003735 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003736 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003737
3738 cricket::VoiceMediaChannel* channels[32];
3739 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003740 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003741 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3742 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003743 if (!channel)
3744 break;
stefan658910c2015-09-03 05:48:32 -07003745 channels[num_channels++] = channel;
3746 }
3747
tfarina5237aaf2015-11-10 23:44:30 -08003748 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003749 EXPECT_EQ(expected, num_channels);
3750
3751 while (num_channels > 0) {
3752 delete channels[--num_channels];
3753 }
stefan658910c2015-09-03 05:48:32 -07003754}
3755
3756// Test that we set our preferred codecs properly.
3757TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003758 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3759 // - Check that our builtin codecs are usable by Channel.
3760 // - The codecs provided by the engine is usable by Channel.
3761 // It does not check that the codecs in the RecvParameters are actually
3762 // what we sent in - though it's probably reasonable to expect so, if
3763 // SetRecvParameters returns true.
3764 // I think it will become clear once audio decoder injection is completed.
3765 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003766 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003767 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003768 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003769 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003770 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3771 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003772 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003773 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003774 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003775}
ossu9def8002017-02-09 05:14:32 -08003776
3777TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3778 std::vector<webrtc::AudioCodecSpec> specs;
3779 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3780 spec1.allow_comfort_noise = false;
3781 spec1.supports_network_adaption = true;
3782 specs.push_back(spec1);
3783 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3784 spec2.allow_comfort_noise = false;
3785 specs.push_back(spec2);
3786 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3787 {{"param1", "value1b"},
3788 {"param2", "value2"}}}));
3789 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3790 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3791
3792 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3793 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3794 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3795 .WillOnce(Return(specs));
3796
3797 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3798 auto codecs = engine.recv_codecs();
3799 EXPECT_EQ(11, codecs.size());
3800
3801 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3802 // check the actual values safely, to provide better test results.
3803 auto get_codec =
3804 [&codecs](size_t index) -> const cricket::AudioCodec& {
3805 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3806 if (codecs.size() > index)
3807 return codecs[index];
3808 return missing_codec;
3809 };
3810
3811 // Ensure the general codecs are generated first and in order.
3812 for (size_t i = 0; i != specs.size(); ++i) {
3813 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3814 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3815 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3816 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3817 }
3818
3819 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003820 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003821 auto find_codec =
3822 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3823 for (size_t i = 0; i != codecs.size(); ++i) {
3824 const cricket::AudioCodec& codec = codecs[i];
3825 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3826 codec.clockrate == format.clockrate_hz &&
3827 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003828 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003829 }
3830 }
3831 return -1;
3832 };
3833
3834 // Ensure all supplementary codecs are generated last. Their internal ordering
3835 // is not important.
3836 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3837 const int num_specs = static_cast<int>(specs.size());
3838 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3839 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3840 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3841 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3842 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3843 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3844 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3845}