blob: 1b7b5697aa574081764bd5516bc5748728f5d0be [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
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010013#include "webrtc/pc/channel.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"
16#include "webrtc/base/gunit.h"
Fredrik Solenberg709ed672015-09-15 12:26:33 +020017#include "webrtc/call.h"
stefanba4c0e42016-02-04 04:12:24 -080018#include "webrtc/p2p/base/faketransportcontroller.h"
19#include "webrtc/test/field_trial.h"
skvlad11a9cbf2016-10-07 11:53:05 -070020#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080021#include "webrtc/media/base/fakemediaengine.h"
22#include "webrtc/media/base/fakenetworkinterface.h"
23#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080024#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010025#include "webrtc/media/engine/fakewebrtccall.h"
26#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
27#include "webrtc/media/engine/webrtcvoiceengine.h"
ossu29b1a8d2016-06-13 07:34:51 -070028#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
29#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070030#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070031#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
solenbergbc37fc82016-04-04 09:54:44 -070033using testing::Return;
34using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000035
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020036namespace {
37
deadbeef67cf2c12016-04-13 10:07:16 -070038const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
39const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
40const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
41const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
42const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070043const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
44const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080045const cricket::AudioCodec
46 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
47const cricket::AudioCodec
48 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
49
solenberg85a04962015-10-27 03:35:21 -070050const uint32_t kSsrc1 = 0x99;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080051const uint32_t kSsrc2 = 2;
52const uint32_t kSsrc3 = 3;
solenberg7602aab2016-11-14 11:30:07 -080053const uint32_t kSsrc4 = 0x42;
solenberg85a04962015-10-27 03:35:21 -070054const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055
solenberg971cab02016-06-14 10:02:41 -070056constexpr int kRtpHistoryMs = 5000;
57
henrike@webrtc.org28e20752013-07-10 00:45:36 +000058class FakeVoEWrapper : public cricket::VoEWrapper {
59 public:
60 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
61 : cricket::VoEWrapper(engine, // processing
62 engine, // base
63 engine, // codec
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 engine, // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 engine) { // volume
66 }
67};
skvlad11a9cbf2016-10-07 11:53:05 -070068
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020069} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070
solenbergff976312016-03-30 23:28:51 -070071// Tests that our stub library "works".
72TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070073 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
74 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
75 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070076 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
77 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
78 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -070079 StrictMock<webrtc::test::MockAudioProcessing> apm;
80 EXPECT_CALL(apm, ApplyConfig(testing::_));
81 EXPECT_CALL(apm, SetExtraOptions(testing::_));
82 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
83 cricket::FakeWebRtcVoiceEngine voe(&apm);
solenbergff976312016-03-30 23:28:51 -070084 EXPECT_FALSE(voe.IsInited());
85 {
ossuc54071d2016-08-17 02:45:41 -070086 cricket::WebRtcVoiceEngine engine(
87 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(),
88 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -070089 EXPECT_TRUE(voe.IsInited());
90 }
91 EXPECT_FALSE(voe.IsInited());
92}
93
deadbeef884f5852016-01-15 09:20:04 -080094class FakeAudioSink : public webrtc::AudioSinkInterface {
95 public:
96 void OnData(const Data& audio) override {}
97};
98
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080099class FakeAudioSource : public cricket::AudioSource {
100 void SetSink(Sink* sink) override {}
101};
102
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103class WebRtcVoiceEngineTestFake : public testing::Test {
104 public:
stefanba4c0e42016-02-04 04:12:24 -0800105 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
106
107 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg059fb442016-10-26 05:12:24 -0700108 : call_(webrtc::Call::Config(&event_log_)), voe_(&apm_),
skvlad11a9cbf2016-10-07 11:53:05 -0700109 override_field_trials_(field_trials) {
ossuc54071d2016-08-17 02:45:41 -0700110 auto factory = webrtc::MockAudioDecoderFactory::CreateUnusedFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700111 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
112 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700113 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -0700116 EXPECT_CALL(apm_, ApplyConfig(testing::_));
117 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
118 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
ossuc54071d2016-08-17 02:45:41 -0700119 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, factory,
solenbergbc37fc82016-04-04 09:54:44 -0700120 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200121 send_parameters_.codecs.push_back(kPcmuCodec);
122 recv_parameters_.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123 }
solenberg8189b022016-06-14 12:13:00 -0700124
solenbergff976312016-03-30 23:28:51 -0700125 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700126 EXPECT_CALL(apm_, ApplyConfig(testing::_));
127 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700128 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
129 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200130 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000131 }
solenberg8189b022016-06-14 12:13:00 -0700132
solenbergff976312016-03-30 23:28:51 -0700133 bool SetupRecvStream() {
134 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700135 return false;
136 }
solenberg8189b022016-06-14 12:13:00 -0700137 return AddRecvStream(kSsrc1);
solenberg1ac56142015-10-13 03:58:19 -0700138 }
solenberg8189b022016-06-14 12:13:00 -0700139
solenbergff976312016-03-30 23:28:51 -0700140 bool SetupSendStream() {
141 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000142 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143 }
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800144 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1))) {
145 return false;
146 }
solenberg059fb442016-10-26 05:12:24 -0700147 EXPECT_CALL(apm_, set_output_will_be_muted(false));
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800148 return channel_->SetAudioSend(kSsrc1, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149 }
solenberg8189b022016-06-14 12:13:00 -0700150
151 bool AddRecvStream(uint32_t ssrc) {
152 EXPECT_TRUE(channel_);
153 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
154 }
155
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000156 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700157 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700158 // Remove stream added in Setup.
solenberg3a941542015-11-16 07:34:50 -0800159 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg85a04962015-10-27 03:35:21 -0700160 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
solenberg0a617e22015-10-20 15:49:38 -0700161 // Verify the channel does not exist.
solenberg3a941542015-11-16 07:34:50 -0800162 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000163 }
solenberg8189b022016-06-14 12:13:00 -0700164
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700166 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000167 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 }
solenberg8189b022016-06-14 12:13:00 -0700169
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200170 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 }
173
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100174 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
175 const auto* send_stream = call_.GetAudioSendStream(ssrc);
176 EXPECT_TRUE(send_stream);
177 return *send_stream;
178 }
179
deadbeef884f5852016-01-15 09:20:04 -0800180 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
181 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
182 EXPECT_TRUE(recv_stream);
183 return *recv_stream;
184 }
185
solenberg3a941542015-11-16 07:34:50 -0800186 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800187 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800188 }
189
solenberg7add0582015-11-20 09:59:34 -0800190 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800191 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800192 }
193
solenberg059fb442016-10-26 05:12:24 -0700194 void SetSend(bool enable) {
195 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700196 if (enable) {
197 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
198 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
199 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700200 EXPECT_CALL(apm_, ApplyConfig(testing::_));
201 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700202 }
solenberg059fb442016-10-26 05:12:24 -0700203 channel_->SetSend(enable);
204 }
205
206 void SetSendParameters(const cricket::AudioSendParameters& params) {
207 EXPECT_CALL(apm_, ApplyConfig(testing::_));
208 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
209 ASSERT_TRUE(channel_);
210 EXPECT_TRUE(channel_->SetSendParameters(params));
211 }
212
minyue6b825df2016-10-31 04:08:32 -0700213 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
214 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700215 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
216 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700217 if (enable && options) {
218 EXPECT_CALL(apm_, ApplyConfig(testing::_));
219 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
220 }
221 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700222 }
223
Peter Boström0c4e06b2015-10-07 12:23:21 +0200224 void TestInsertDtmf(uint32_t ssrc, bool caller) {
solenbergff976312016-03-30 23:28:51 -0700225 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000226 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700227 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000228 // send stream.
229 EXPECT_TRUE(channel_->AddSendStream(
230 cricket::StreamParams::CreateLegacy(kSsrc1)));
231 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000232
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700234 SetSendParameters(send_parameters_);
235 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800237 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenberg2779bab2016-11-17 04:45:19 -0800238 send_parameters_.codecs.push_back(kTelephoneEventCodec1);
solenberg059fb442016-10-26 05:12:24 -0700239 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000241
242 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700243 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800244 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000245 EXPECT_TRUE(channel_->AddSendStream(
246 cricket::StreamParams::CreateLegacy(kSsrc1)));
247 }
248
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800250 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100252 // Test send.
253 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
254 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
255 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800256 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100257 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
solenberg2779bab2016-11-17 04:45:19 -0800258 EXPECT_EQ(kTelephoneEventCodec1.id, telephone_event.payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100259 EXPECT_EQ(2, telephone_event.event_code);
260 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 }
262
263 // Test that send bandwidth is set correctly.
264 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000265 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
266 // |expected_result| is the expected result from SetMaxSendBandwidth().
267 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700268 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
269 int max_bitrate,
270 bool expected_result,
271 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200272 cricket::AudioSendParameters parameters;
273 parameters.codecs.push_back(codec);
274 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700275 if (expected_result) {
276 SetSendParameters(parameters);
277 } else {
278 EXPECT_FALSE(channel_->SetSendParameters(parameters));
279 }
minyue7a973442016-10-20 03:27:12 -0700280 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 }
282
skvlade0d46372016-04-07 22:59:22 -0700283 // Sets the per-stream maximum bitrate limit for the specified SSRC.
284 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700285 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700286 EXPECT_EQ(1UL, parameters.encodings.size());
287
288 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700289 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700290 }
291
solenberg059fb442016-10-26 05:12:24 -0700292 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700293 cricket::AudioSendParameters send_parameters;
294 send_parameters.codecs.push_back(codec);
295 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700296 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700297 }
298
minyue7a973442016-10-20 03:27:12 -0700299 void CheckSendCodec(int32_t ssrc,
300 const char expected_name[],
301 int expected_channels,
302 int expected_bitrate) {
303 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
304 EXPECT_STREQ(expected_name, codec.plname);
305 EXPECT_EQ(expected_channels, codec.channels);
306 EXPECT_EQ(expected_bitrate, codec.rate);
307 }
308
309 int GetOpusMaxPlaybackRate(int32_t ssrc) {
310 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
311 }
312
313 bool GetOpusDtx(int32_t ssrc) {
314 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
315 }
316
317 bool GetCodecFec(int32_t ssrc) {
318 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
319 }
320
skvlade0d46372016-04-07 22:59:22 -0700321 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700322 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
323 }
324
325 int GetCodecPacSize(int32_t ssrc) {
326 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700327 }
328
minyue6b825df2016-10-31 04:08:32 -0700329 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
330 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
331 }
332
skvlade0d46372016-04-07 22:59:22 -0700333 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
334 int global_max,
335 int stream_max,
336 bool expected_result,
337 int expected_codec_bitrate) {
338 // Clear the bitrate limit from the previous test case.
339 EXPECT_TRUE(SetMaxBitrateForStream(kSsrc1, -1));
340
341 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700342 SetGlobalMaxBitrate(codec, global_max);
skvlade0d46372016-04-07 22:59:22 -0700343 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrc1, stream_max));
344
345 // Verify that reading back the parameters gives results
346 // consistent with the Set() result.
347 webrtc::RtpParameters resulting_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700348 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -0700349 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
350 EXPECT_EQ(expected_result ? stream_max : -1,
351 resulting_parameters.encodings[0].max_bitrate_bps);
352
353 // Verify that the codec settings have the expected bitrate.
354 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrc1));
355 }
356
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000357 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700358 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000359
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000360 // Ensure extensions are off by default.
solenberg3a941542015-11-16 07:34:50 -0800361 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000362
363 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700364 send_parameters_.extensions.push_back(
365 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700366 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800367 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000368
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000369 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200370 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700371 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800372 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000373
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000374 // Ensure extension is set properly.
375 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700376 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700377 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800378 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700379 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800380 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000381
solenberg7add0582015-11-20 09:59:34 -0800382 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000383 EXPECT_TRUE(channel_->AddSendStream(
solenberg0a617e22015-10-20 15:49:38 -0700384 cricket::StreamParams::CreateLegacy(kSsrc2)));
solenberg3a941542015-11-16 07:34:50 -0800385 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
386 call_.GetAudioSendStream(kSsrc2));
387 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700388 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800389 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000390
391 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200392 send_parameters_.codecs.push_back(kPcmuCodec);
393 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700394 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800395 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
396 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000397 }
398
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000399 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700400 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000401
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000402 // Ensure extensions are off by default.
solenberg7add0582015-11-20 09:59:34 -0800403 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000404
405 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700406 recv_parameters_.extensions.push_back(
407 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800408 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
409 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000410
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000411 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800412 recv_parameters_.extensions.clear();
413 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
414 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000415
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000416 // Ensure extension is set properly.
417 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700418 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800419 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
420 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700421 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800422 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000423
solenberg7add0582015-11-20 09:59:34 -0800424 // Ensure extension is set properly on new stream.
solenberg8189b022016-06-14 12:13:00 -0700425 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -0800426 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
427 call_.GetAudioReceiveStream(kSsrc2));
428 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700429 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800430 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000431
432 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800433 recv_parameters_.extensions.clear();
434 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
435 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
436 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000437 }
438
solenberg85a04962015-10-27 03:35:21 -0700439 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
440 webrtc::AudioSendStream::Stats stats;
441 stats.local_ssrc = 12;
442 stats.bytes_sent = 345;
443 stats.packets_sent = 678;
444 stats.packets_lost = 9012;
445 stats.fraction_lost = 34.56f;
446 stats.codec_name = "codec_name_send";
447 stats.ext_seqnum = 789;
448 stats.jitter_ms = 12;
449 stats.rtt_ms = 345;
450 stats.audio_level = 678;
451 stats.aec_quality_min = 9.01f;
452 stats.echo_delay_median_ms = 234;
453 stats.echo_delay_std_ms = 567;
454 stats.echo_return_loss = 890;
455 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700456 stats.residual_echo_likelihood = 0.432f;
solenberg85a04962015-10-27 03:35:21 -0700457 stats.typing_noise_detected = true;
458 return stats;
459 }
460 void SetAudioSendStreamStats() {
461 for (auto* s : call_.GetAudioSendStreams()) {
462 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200463 }
solenberg85a04962015-10-27 03:35:21 -0700464 }
solenberg566ef242015-11-06 15:34:49 -0800465 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
466 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700467 const auto stats = GetAudioSendStreamStats();
468 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
469 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
470 EXPECT_EQ(info.packets_sent, stats.packets_sent);
471 EXPECT_EQ(info.packets_lost, stats.packets_lost);
472 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
473 EXPECT_EQ(info.codec_name, stats.codec_name);
474 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
475 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
476 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
477 EXPECT_EQ(info.audio_level, stats.audio_level);
478 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
479 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
480 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
481 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
482 EXPECT_EQ(info.echo_return_loss_enhancement,
483 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700484 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
solenberg566ef242015-11-06 15:34:49 -0800485 EXPECT_EQ(info.typing_noise_detected,
486 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700487 }
488
489 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
490 webrtc::AudioReceiveStream::Stats stats;
491 stats.remote_ssrc = 123;
492 stats.bytes_rcvd = 456;
493 stats.packets_rcvd = 768;
494 stats.packets_lost = 101;
495 stats.fraction_lost = 23.45f;
496 stats.codec_name = "codec_name_recv";
497 stats.ext_seqnum = 678;
498 stats.jitter_ms = 901;
499 stats.jitter_buffer_ms = 234;
500 stats.jitter_buffer_preferred_ms = 567;
501 stats.delay_estimate_ms = 890;
502 stats.audio_level = 1234;
503 stats.expand_rate = 5.67f;
504 stats.speech_expand_rate = 8.90f;
505 stats.secondary_decoded_rate = 1.23f;
506 stats.accelerate_rate = 4.56f;
507 stats.preemptive_expand_rate = 7.89f;
508 stats.decoding_calls_to_silence_generator = 12;
509 stats.decoding_calls_to_neteq = 345;
510 stats.decoding_normal = 67890;
511 stats.decoding_plc = 1234;
512 stats.decoding_cng = 5678;
513 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700514 stats.decoding_muted_output = 3456;
515 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200516 return stats;
517 }
518 void SetAudioReceiveStreamStats() {
519 for (auto* s : call_.GetAudioReceiveStreams()) {
520 s->SetStats(GetAudioReceiveStreamStats());
521 }
522 }
523 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700524 const auto stats = GetAudioReceiveStreamStats();
525 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
526 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
527 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
528 EXPECT_EQ(info.packets_lost, stats.packets_lost);
529 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
530 EXPECT_EQ(info.codec_name, stats.codec_name);
531 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
532 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
533 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200534 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700535 stats.jitter_buffer_preferred_ms);
536 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
537 EXPECT_EQ(info.audio_level, stats.audio_level);
538 EXPECT_EQ(info.expand_rate, stats.expand_rate);
539 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
540 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
541 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
542 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200543 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700544 stats.decoding_calls_to_silence_generator);
545 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
546 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
547 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
548 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
549 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700550 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700551 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200552 }
553
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700555 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700556 StrictMock<webrtc::test::MockAudioProcessing> apm_;
skvlad11a9cbf2016-10-07 11:53:05 -0700557 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200558 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700560 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700561 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200562 cricket::AudioSendParameters send_parameters_;
563 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800564 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800565 private:
566 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567};
568
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569// Tests that we can create and destroy a channel.
570TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700571 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572}
573
solenberg31fec402016-05-06 02:13:12 -0700574// Test that we can add a send stream and that it has the correct defaults.
575TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
576 EXPECT_TRUE(SetupChannel());
577 EXPECT_TRUE(
578 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
579 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrc1);
580 EXPECT_EQ(kSsrc1, config.rtp.ssrc);
581 EXPECT_EQ("", config.rtp.c_name);
582 EXPECT_EQ(0u, config.rtp.extensions.size());
583 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
584 config.send_transport);
585}
586
587// Test that we can add a receive stream and that it has the correct defaults.
588TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
589 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -0700590 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg31fec402016-05-06 02:13:12 -0700591 const webrtc::AudioReceiveStream::Config& config =
592 GetRecvStreamConfig(kSsrc1);
593 EXPECT_EQ(kSsrc1, config.rtp.remote_ssrc);
594 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
595 EXPECT_FALSE(config.rtp.transport_cc);
596 EXPECT_EQ(0u, config.rtp.extensions.size());
597 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
598 config.rtcp_send_transport);
599 EXPECT_EQ("", config.sync_group);
600}
601
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000602// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700603// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700604// TODO(ossu): This test should move into a separate builtin audio codecs
605// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700606TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700607 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608 ASSERT_FALSE(codecs.empty());
609 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
610 EXPECT_EQ(48000, codecs[0].clockrate);
611 EXPECT_EQ(2, codecs[0].channels);
612 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000613}
614
stefanba4c0e42016-02-04 04:12:24 -0800615TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700616 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800617 bool opus_found = false;
618 for (cricket::AudioCodec codec : codecs) {
619 if (codec.name == "opus") {
620 EXPECT_TRUE(HasTransportCc(codec));
621 opus_found = true;
622 }
623 }
624 EXPECT_TRUE(opus_found);
625}
626
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000627// Tests that we can find codecs by name or id, and that we interpret the
628// clockrate and bitrate fields properly.
629TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
630 cricket::AudioCodec codec;
631 webrtc::CodecInst codec_inst;
632 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800633 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000634 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800635 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800637 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
638 &codec_inst));
639 // Find telephone-event with explicit clockrate and 0 bitrate.
640 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800641 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642 // Find ISAC with a different payload id.
643 codec = kIsacCodec;
644 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800645 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646 EXPECT_EQ(codec.id, codec_inst.pltype);
647 // Find PCMU with a 0 clockrate.
648 codec = kPcmuCodec;
649 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800650 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651 EXPECT_EQ(codec.id, codec_inst.pltype);
652 EXPECT_EQ(8000, codec_inst.plfreq);
653 // Find PCMU with a 0 bitrate.
654 codec = kPcmuCodec;
655 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800656 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657 EXPECT_EQ(codec.id, codec_inst.pltype);
658 EXPECT_EQ(64000, codec_inst.rate);
659 // Find ISAC with an explicit bitrate.
660 codec = kIsacCodec;
661 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800662 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663 EXPECT_EQ(codec.id, codec_inst.pltype);
664 EXPECT_EQ(32000, codec_inst.rate);
665}
666
667// Test that we set our inbound codecs properly, including changing PT.
668TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700669 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200670 cricket::AudioRecvParameters parameters;
671 parameters.codecs.push_back(kIsacCodec);
672 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800673 parameters.codecs.push_back(kTelephoneEventCodec1);
674 parameters.codecs.push_back(kTelephoneEventCodec2);
675 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200676 parameters.codecs[2].id = 126;
677 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700678 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700679 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800680
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000681 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800682 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 gcodec.plfreq = 16000;
684 gcodec.channels = 1;
685 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
686 EXPECT_EQ(106, gcodec.pltype);
687 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800688
tfarina5237aaf2015-11-10 23:44:30 -0800689 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690 gcodec.plfreq = 8000;
691 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
692 EXPECT_EQ(126, gcodec.pltype);
693 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800694
695 gcodec.plfreq = 32000;
696 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
697 EXPECT_EQ(107, gcodec.pltype);
698 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699}
700
701// Test that we fail to set an unknown inbound codec.
702TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700703 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200704 cricket::AudioRecvParameters parameters;
705 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700706 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200707 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708}
709
710// Test that we fail if we have duplicate types in the inbound list.
711TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700712 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200713 cricket::AudioRecvParameters parameters;
714 parameters.codecs.push_back(kIsacCodec);
715 parameters.codecs.push_back(kCn16000Codec);
716 parameters.codecs[1].id = kIsacCodec.id;
717 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718}
719
720// Test that we can decode OPUS without stereo parameters.
721TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700722 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200723 cricket::AudioRecvParameters parameters;
724 parameters.codecs.push_back(kIsacCodec);
725 parameters.codecs.push_back(kPcmuCodec);
726 parameters.codecs.push_back(kOpusCodec);
727 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700728 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700729 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800731 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732 // Even without stereo parameters, recv codecs still specify channels = 2.
733 EXPECT_EQ(2, opus.channels);
734 EXPECT_EQ(111, opus.pltype);
735 EXPECT_STREQ("opus", opus.plname);
736 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700737 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 EXPECT_EQ(111, opus.pltype);
739}
740
741// Test that we can decode OPUS with stereo = 0.
742TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700743 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200744 cricket::AudioRecvParameters parameters;
745 parameters.codecs.push_back(kIsacCodec);
746 parameters.codecs.push_back(kPcmuCodec);
747 parameters.codecs.push_back(kOpusCodec);
748 parameters.codecs[2].params["stereo"] = "0";
749 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700750 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 int channel_num2 = voe_.GetLastChannel();
752 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800753 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754 // Even when stereo is off, recv codecs still specify channels = 2.
755 EXPECT_EQ(2, opus.channels);
756 EXPECT_EQ(111, opus.pltype);
757 EXPECT_STREQ("opus", opus.plname);
758 opus.pltype = 0;
759 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
760 EXPECT_EQ(111, opus.pltype);
761}
762
763// Test that we can decode OPUS with stereo = 1.
764TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700765 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200766 cricket::AudioRecvParameters parameters;
767 parameters.codecs.push_back(kIsacCodec);
768 parameters.codecs.push_back(kPcmuCodec);
769 parameters.codecs.push_back(kOpusCodec);
770 parameters.codecs[2].params["stereo"] = "1";
771 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700772 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 int channel_num2 = voe_.GetLastChannel();
774 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800775 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 EXPECT_EQ(2, opus.channels);
777 EXPECT_EQ(111, opus.pltype);
778 EXPECT_STREQ("opus", opus.plname);
779 opus.pltype = 0;
780 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
781 EXPECT_EQ(111, opus.pltype);
782}
783
784// Test that changes to recv codecs are applied to all streams.
785TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700786 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200787 cricket::AudioRecvParameters parameters;
788 parameters.codecs.push_back(kIsacCodec);
789 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800790 parameters.codecs.push_back(kTelephoneEventCodec1);
791 parameters.codecs.push_back(kTelephoneEventCodec2);
792 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200793 parameters.codecs[2].id = 126;
794 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700795 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800797
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800799 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 gcodec.plfreq = 16000;
801 gcodec.channels = 1;
802 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
803 EXPECT_EQ(106, gcodec.pltype);
804 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800805
tfarina5237aaf2015-11-10 23:44:30 -0800806 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 gcodec.plfreq = 8000;
808 gcodec.channels = 1;
809 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
810 EXPECT_EQ(126, gcodec.pltype);
811 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800812
813 gcodec.plfreq = 32000;
814 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
815 EXPECT_EQ(107, gcodec.pltype);
816 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817}
818
819TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700820 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200821 cricket::AudioRecvParameters parameters;
822 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800823 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825
826 int channel_num2 = voe_.GetLastChannel();
827 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800828 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 gcodec.plfreq = 16000;
830 gcodec.channels = 1;
831 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
832 EXPECT_EQ(106, gcodec.pltype);
833 EXPECT_STREQ("ISAC", gcodec.plname);
834}
835
836// Test that we can apply the same set of codecs again while playing.
837TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700838 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200839 cricket::AudioRecvParameters parameters;
840 parameters.codecs.push_back(kIsacCodec);
841 parameters.codecs.push_back(kCn16000Codec);
842 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700843 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845
846 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200847 parameters.codecs[0].id = 127;
848 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700849 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850}
851
852// Test that we can add a codec while playing.
853TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700854 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 cricket::AudioRecvParameters parameters;
856 parameters.codecs.push_back(kIsacCodec);
857 parameters.codecs.push_back(kCn16000Codec);
858 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700859 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 parameters.codecs.push_back(kOpusCodec);
862 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700863 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800865 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
867}
868
869TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000872 // Test that when autobw is enabled, bitrate is kept as the default
873 // value. autobw is enabled for the following tests because the target
874 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875
876 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700877 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878
879 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700880 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700883 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884}
885
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000886TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700887 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000889 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
891 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700892 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
893 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
894 // Rates above the max (56000) should be capped.
895 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700898 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
899 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
900 // Rates above the max (510000) should be capped.
901 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902}
903
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000904TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700905 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000906
907 // Test that we can only set a maximum bitrate for a fixed-rate codec
908 // if it's bigger than the fixed rate.
909
910 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700911 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
912 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
913 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
914 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
915 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
916 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
917 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000918}
919
920TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700921 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 const int kDesiredBitrate = 128000;
923 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700924 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200925 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700926 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000927
928 EXPECT_TRUE(channel_->AddSendStream(
929 cricket::StreamParams::CreateLegacy(kSsrc1)));
930
minyue7a973442016-10-20 03:27:12 -0700931 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrc1));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000932}
933
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934// Test that bitrate cannot be set for CBR codecs.
935// Bitrate is ignored if it is higher than the fixed bitrate.
936// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000937TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
940 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700941 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700942 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200943
944 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700945 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700946 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947
948 send_parameters_.max_bandwidth_bps = 128;
949 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
minyue7a973442016-10-20 03:27:12 -0700950 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951}
952
skvlade0d46372016-04-07 22:59:22 -0700953// Test that the per-stream bitrate limit and the global
954// bitrate limit both apply.
955TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
956 EXPECT_TRUE(SetupSendStream());
957
958 // opus, default bitrate == 64000.
959 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
960 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
961 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
962 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
963
964 // CBR codecs allow both maximums to exceed the bitrate.
965 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
966 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
967 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
968 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
969
970 // CBR codecs don't allow per stream maximums to be too low.
971 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
972 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
973}
974
975// Test that an attempt to set RtpParameters for a stream that does not exist
976// fails.
977TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
978 EXPECT_TRUE(SetupChannel());
979 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700980 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -0700981 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
982
983 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700984 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -0700985}
986
987TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700988 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -0700989 // This test verifies that setting RtpParameters succeeds only if
990 // the structure contains exactly one encoding.
991 // TODO(skvlad): Update this test when we start supporting setting parameters
992 // for each encoding individually.
993
994 EXPECT_TRUE(SetupSendStream());
995 // Setting RtpParameters with no encoding is expected to fail.
996 webrtc::RtpParameters parameters;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700997 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -0700998 // Setting RtpParameters with exactly one encoding should succeed.
999 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001000 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -07001001 // Two or more encodings should result in failure.
1002 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001003 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -07001004}
1005
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001006// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001007// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001008TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1009 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001010 SetSend(true);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001011 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1012 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001013 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001014 ASSERT_EQ(1u, parameters.encodings.size());
1015 ASSERT_TRUE(parameters.encodings[0].active);
1016 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001017 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001018 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
1019
1020 // Now change it back to active and verify we resume sending.
1021 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001022 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001023 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1024}
1025
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001026// Test that SetRtpSendParameters configures the correct encoding channel for
1027// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001028TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1029 SetupForMultiSendStream();
1030 // Create send streams.
1031 for (uint32_t ssrc : kSsrcs4) {
1032 EXPECT_TRUE(
1033 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1034 }
1035 // Configure one stream to be limited by the stream config, another to be
1036 // limited by the global max, and the third one with no per-stream limit
1037 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001038 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001039 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1040 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1041 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1042
1043 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1044 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1045 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1046
1047 // Remove the global cap; the streams should switch to their respective
1048 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001049 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001050 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1051 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1052 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1053}
1054
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001055// Test that GetRtpSendParameters returns the currently configured codecs.
1056TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001057 EXPECT_TRUE(SetupSendStream());
1058 cricket::AudioSendParameters parameters;
1059 parameters.codecs.push_back(kIsacCodec);
1060 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001061 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001062
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001063 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001064 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001065 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1066 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001067}
1068
1069// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001070TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001071 EXPECT_TRUE(SetupSendStream());
1072 cricket::AudioSendParameters parameters;
1073 parameters.codecs.push_back(kIsacCodec);
1074 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001075 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001076
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001077 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001078
1079 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001080 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001081
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001082 // ... And this shouldn't change the params returned by GetRtpSendParameters.
1083 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrc1);
1084 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrc1));
1085}
1086
1087// Test that GetRtpReceiveParameters returns the currently configured codecs.
1088TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1089 EXPECT_TRUE(SetupRecvStream());
1090 cricket::AudioRecvParameters parameters;
1091 parameters.codecs.push_back(kIsacCodec);
1092 parameters.codecs.push_back(kPcmuCodec);
1093 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1094
1095 webrtc::RtpParameters rtp_parameters =
1096 channel_->GetRtpReceiveParameters(kSsrc1);
1097 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1098 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1099 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1100}
1101
1102// Test that if we set/get parameters multiple times, we get the same results.
1103TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1104 EXPECT_TRUE(SetupRecvStream());
1105 cricket::AudioRecvParameters parameters;
1106 parameters.codecs.push_back(kIsacCodec);
1107 parameters.codecs.push_back(kPcmuCodec);
1108 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1109
1110 webrtc::RtpParameters initial_params =
1111 channel_->GetRtpReceiveParameters(kSsrc1);
1112
1113 // We should be able to set the params we just got.
1114 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrc1, initial_params));
1115
1116 // ... And this shouldn't change the params returned by
1117 // GetRtpReceiveParameters.
1118 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrc1);
1119 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrc1));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001120}
1121
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001122// Test that we apply codecs properly.
1123TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001124 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001125 cricket::AudioSendParameters parameters;
1126 parameters.codecs.push_back(kIsacCodec);
1127 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001128 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001129 parameters.codecs[0].id = 96;
1130 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001131 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001132 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001133 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
1134 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1135 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1136 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1137 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1138 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1139 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1140 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001141 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142}
1143
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001144// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1145// to apply.
1146TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001147 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001148 cricket::AudioSendParameters parameters;
1149 parameters.codecs.push_back(kIsacCodec);
1150 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001151 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001152 parameters.codecs[0].id = 96;
1153 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001154 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001155 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001156 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001157 // Calling SetSendCodec again with same codec which is already set.
1158 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001159 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001160 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001161}
1162
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001163// Verify that G722 is set with 16000 samples per second to WebRTC.
1164TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001165 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001166 cricket::AudioSendParameters parameters;
1167 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001168 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001169 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001170 EXPECT_STREQ("G722", gcodec.plname);
1171 EXPECT_EQ(1, gcodec.channels);
1172 EXPECT_EQ(16000, gcodec.plfreq);
1173}
1174
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001175// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001176TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001177 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001178 cricket::AudioSendParameters parameters;
1179 parameters.codecs.push_back(kOpusCodec);
1180 parameters.codecs[0].bitrate = 0;
1181 parameters.codecs[0].clockrate = 50000;
1182 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183}
1184
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001185// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001186TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001187 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001188 cricket::AudioSendParameters parameters;
1189 parameters.codecs.push_back(kOpusCodec);
1190 parameters.codecs[0].bitrate = 0;
1191 parameters.codecs[0].channels = 0;
1192 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001193}
1194
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001195// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001196TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001197 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001198 cricket::AudioSendParameters parameters;
1199 parameters.codecs.push_back(kOpusCodec);
1200 parameters.codecs[0].bitrate = 0;
1201 parameters.codecs[0].channels = 0;
1202 parameters.codecs[0].params["stereo"] = "1";
1203 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001204}
1205
1206// Test that if channel is 1 for opus and there's no stereo, we fail.
1207TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001208 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001209 cricket::AudioSendParameters parameters;
1210 parameters.codecs.push_back(kOpusCodec);
1211 parameters.codecs[0].bitrate = 0;
1212 parameters.codecs[0].channels = 1;
1213 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001214}
1215
1216// Test that if channel is 1 for opus and stereo=0, we fail.
1217TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001218 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001219 cricket::AudioSendParameters parameters;
1220 parameters.codecs.push_back(kOpusCodec);
1221 parameters.codecs[0].bitrate = 0;
1222 parameters.codecs[0].channels = 1;
1223 parameters.codecs[0].params["stereo"] = "0";
1224 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001225}
1226
1227// Test that if channel is 1 for opus and stereo=1, we fail.
1228TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001229 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001230 cricket::AudioSendParameters parameters;
1231 parameters.codecs.push_back(kOpusCodec);
1232 parameters.codecs[0].bitrate = 0;
1233 parameters.codecs[0].channels = 1;
1234 parameters.codecs[0].params["stereo"] = "1";
1235 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001236}
1237
1238// Test that with bitrate=0 and no stereo,
1239// channels and bitrate are 1 and 32000.
1240TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001241 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001242 cricket::AudioSendParameters parameters;
1243 parameters.codecs.push_back(kOpusCodec);
1244 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001245 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001246 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001247}
1248
1249// Test that with bitrate=0 and stereo=0,
1250// channels and bitrate are 1 and 32000.
1251TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001252 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001253 cricket::AudioSendParameters parameters;
1254 parameters.codecs.push_back(kOpusCodec);
1255 parameters.codecs[0].bitrate = 0;
1256 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001257 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001258 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001259}
1260
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001261// Test that with bitrate=invalid and stereo=0,
1262// channels and bitrate are 1 and 32000.
1263TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001264 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001265 cricket::AudioSendParameters parameters;
1266 parameters.codecs.push_back(kOpusCodec);
1267 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001268 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001269 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001270 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001271 CheckSendCodec(kSsrc1, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001272
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001274 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001275 CheckSendCodec(kSsrc1, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001276}
1277
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278// Test that with bitrate=0 and stereo=1,
1279// channels and bitrate are 2 and 64000.
1280TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001281 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001282 cricket::AudioSendParameters parameters;
1283 parameters.codecs.push_back(kOpusCodec);
1284 parameters.codecs[0].bitrate = 0;
1285 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001286 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001287 CheckSendCodec(kSsrc1, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001288}
1289
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001290// Test that with bitrate=invalid and stereo=1,
1291// channels and bitrate are 2 and 64000.
1292TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001293 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kOpusCodec);
1296 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001297 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001299 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001300 CheckSendCodec(kSsrc1, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001301
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001302 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001303 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001304 CheckSendCodec(kSsrc1, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001305}
1306
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307// Test that with bitrate=N and stereo unset,
1308// channels and bitrate are 1 and N.
1309TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001310 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 cricket::AudioSendParameters parameters;
1312 parameters.codecs.push_back(kOpusCodec);
1313 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001314 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001315 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316 EXPECT_EQ(111, gcodec.pltype);
1317 EXPECT_EQ(96000, gcodec.rate);
1318 EXPECT_STREQ("opus", gcodec.plname);
1319 EXPECT_EQ(1, gcodec.channels);
1320 EXPECT_EQ(48000, gcodec.plfreq);
1321}
1322
1323// Test that with bitrate=N and stereo=0,
1324// channels and bitrate are 1 and N.
1325TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001326 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kOpusCodec);
1329 parameters.codecs[0].bitrate = 30000;
1330 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001331 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001332 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
1335// Test that with bitrate=N and without any parameters,
1336// channels and bitrate are 1 and N.
1337TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001338 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 cricket::AudioSendParameters parameters;
1340 parameters.codecs.push_back(kOpusCodec);
1341 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001342 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001343 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
1346// Test that with bitrate=N and stereo=1,
1347// channels and bitrate are 2 and N.
1348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 30000;
1353 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001354 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001355 CheckSendCodec(kSsrc1, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001358// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1359// Also test that the "maxaveragebitrate" can't be set to values outside the
1360// range of 6000 and 510000
1361TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001362 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 cricket::AudioSendParameters parameters;
1364 parameters.codecs.push_back(kOpusCodec);
1365 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001366 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001368 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001369 EXPECT_EQ(6000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001370
1371 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001373 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001374 EXPECT_EQ(510000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001375
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001376 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001378 EXPECT_EQ(200000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001379}
1380
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001381// Test that we can enable NACK with opus as caller.
1382TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001383 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 cricket::AudioSendParameters parameters;
1385 parameters.codecs.push_back(kOpusCodec);
1386 parameters.codecs[0].AddFeedbackParam(
1387 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1388 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001389 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001390 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001391 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392}
1393
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001394// Test that we can enable NACK with opus as callee.
1395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].AddFeedbackParam(
1400 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1401 cricket::kParamValueEmpty));
solenberg8189b022016-06-14 12:13:00 -07001402 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001403 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001404 // NACK should be enabled even with no send stream.
solenberg8189b022016-06-14 12:13:00 -07001405 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001406
1407 EXPECT_TRUE(channel_->AddSendStream(
1408 cricket::StreamParams::CreateLegacy(kSsrc1)));
solenberg971cab02016-06-14 10:02:41 -07001409 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001410}
1411
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412// Test that we can enable NACK on receive streams.
1413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001415 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kOpusCodec);
1418 parameters.codecs[0].AddFeedbackParam(
1419 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1420 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001421 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001422 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001424 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001425 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
1428// Test that we can disable NACK.
1429TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001430 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 cricket::AudioSendParameters parameters;
1432 parameters.codecs.push_back(kOpusCodec);
1433 parameters.codecs[0].AddFeedbackParam(
1434 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1435 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001436 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001437 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 parameters.codecs.clear();
1440 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001441 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001442 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443}
1444
1445// Test that we can disable NACK on receive streams.
1446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001448 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 cricket::AudioSendParameters parameters;
1450 parameters.codecs.push_back(kOpusCodec);
1451 parameters.codecs[0].AddFeedbackParam(
1452 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1453 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001454 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001455 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001456 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 parameters.codecs.clear();
1459 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001461 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001462 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
1465// Test that NACK is enabled on a new receive stream.
1466TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kIsacCodec);
1470 parameters.codecs.push_back(kCn16000Codec);
1471 parameters.codecs[0].AddFeedbackParam(
1472 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1473 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001474 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001475 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476
solenberg8189b022016-06-14 12:13:00 -07001477 EXPECT_TRUE(AddRecvStream(kSsrc2));
1478 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
1479 EXPECT_TRUE(AddRecvStream(kSsrc3));
1480 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc3).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481}
1482
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001483// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001484TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
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);
solenberg059fb442016-10-26 05:12:24 -07001488 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001489 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001490}
1491
1492// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001493TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001494 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 cricket::AudioSendParameters parameters;
1496 parameters.codecs.push_back(kOpusCodec);
1497 parameters.codecs[0].bitrate = 0;
1498 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001499 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001500 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001501}
1502
1503// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001505 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001506 cricket::AudioSendParameters parameters;
1507 parameters.codecs.push_back(kOpusCodec);
1508 parameters.codecs[0].bitrate = 0;
1509 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001510 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001511 EXPECT_TRUE(GetCodecFec(kSsrc1));
1512 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001513}
1514
1515// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001517 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].bitrate = 0;
1521 parameters.codecs[0].params["stereo"] = "1";
1522 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001524 EXPECT_TRUE(GetCodecFec(kSsrc1));
1525 CheckSendCodec(kSsrc1, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001526}
1527
1528// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001530 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 cricket::AudioSendParameters parameters;
1532 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001534 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001535}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001536
1537// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kIsacCodec);
1542 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001544 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001545}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001546
1547// Test that Opus FEC status can be changed.
1548TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001553 EXPECT_FALSE(GetCodecFec(kSsrc1));
1554
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001555 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001557 EXPECT_TRUE(GetCodecFec(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001558}
1559
stefanba4c0e42016-02-04 04:12:24 -08001560TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001561 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001562 cricket::AudioSendParameters send_parameters;
1563 send_parameters.codecs.push_back(kOpusCodec);
1564 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001565 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001566
1567 cricket::AudioRecvParameters recv_parameters;
1568 recv_parameters.codecs.push_back(kIsacCodec);
1569 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg8189b022016-06-14 12:13:00 -07001570 EXPECT_TRUE(AddRecvStream(kSsrc1));
stefanba4c0e42016-02-04 04:12:24 -08001571 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1572 EXPECT_FALSE(
1573 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1574
ossudedfd282016-06-14 07:12:39 -07001575 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001577 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1578 EXPECT_TRUE(
1579 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1580}
1581
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001582// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1583TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001584 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].bitrate = 0;
1588 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001590 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
1591 EXPECT_EQ(12000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001592
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001594 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001595 EXPECT_EQ(24000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001596}
1597
1598// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1599TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001600 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001601 cricket::AudioSendParameters parameters;
1602 parameters.codecs.push_back(kOpusCodec);
1603 parameters.codecs[0].bitrate = 0;
1604 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001606 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrc1));
1607 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001608
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001611 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001612}
1613
1614// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1615TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 cricket::AudioSendParameters parameters;
1618 parameters.codecs.push_back(kOpusCodec);
1619 parameters.codecs[0].bitrate = 0;
1620 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001622 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrc1));
1623 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001624
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001627 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001628}
1629
1630// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1631TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001633 cricket::AudioSendParameters parameters;
1634 parameters.codecs.push_back(kOpusCodec);
1635 parameters.codecs[0].bitrate = 0;
1636 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001638 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrc1));
1639 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001640
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001641 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001642 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001643 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001644}
1645
1646// Test 24000 < maxplaybackrate triggers Opus full band mode.
1647TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001648 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001649 cricket::AudioSendParameters parameters;
1650 parameters.codecs.push_back(kOpusCodec);
1651 parameters.codecs[0].bitrate = 0;
1652 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001654 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrc1));
1655 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001656
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001657 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001659 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001660}
1661
1662// Test Opus that without maxplaybackrate, default playback rate is used.
1663TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001664 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001665 cricket::AudioSendParameters parameters;
1666 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001667 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001668 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001669}
1670
1671// Test the with non-Opus, maxplaybackrate has no effect.
1672TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001673 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001674 cricket::AudioSendParameters parameters;
1675 parameters.codecs.push_back(kIsacCodec);
1676 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001678 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001679}
1680
1681// Test maxplaybackrate can be set on two streams.
1682TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001683 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001684 cricket::AudioSendParameters parameters;
1685 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001687 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001688
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001691 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001692
1693 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
minyue7a973442016-10-20 03:27:12 -07001694 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc2));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001695}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001696
Minyue Li7100dcd2015-03-27 05:05:59 +01001697// Test that with usedtx=0, Opus DTX is off.
1698TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 cricket::AudioSendParameters parameters;
1701 parameters.codecs.push_back(kOpusCodec);
1702 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001704 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001705}
1706
1707// Test that with usedtx=1, Opus DTX is on.
1708TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001709 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 cricket::AudioSendParameters parameters;
1711 parameters.codecs.push_back(kOpusCodec);
1712 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001714 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001715}
1716
1717// Test that usedtx=1 works with stereo Opus.
1718TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001719 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 cricket::AudioSendParameters parameters;
1721 parameters.codecs.push_back(kOpusCodec);
1722 parameters.codecs[0].params["usedtx"] = "1";
1723 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001724 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001725 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001726}
1727
1728// Test that usedtx=1 does not work with non Opus.
1729TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001730 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 cricket::AudioSendParameters parameters;
1732 parameters.codecs.push_back(kIsacCodec);
1733 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001735 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001736}
1737
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001738// Test that we can switch back and forth between Opus and ISAC with CN.
1739TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001740 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001741
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 cricket::AudioSendParameters opus_parameters;
1743 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001745 {
1746 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1747 EXPECT_EQ(111, gcodec.pltype);
1748 EXPECT_STREQ("opus", gcodec.plname);
1749 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 cricket::AudioSendParameters isac_parameters;
1752 isac_parameters.codecs.push_back(kIsacCodec);
1753 isac_parameters.codecs.push_back(kCn16000Codec);
1754 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001756 {
1757 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1758 EXPECT_EQ(103, gcodec.pltype);
1759 EXPECT_STREQ("ISAC", gcodec.plname);
1760 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001761
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
1764 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1765 EXPECT_EQ(111, gcodec.pltype);
1766 EXPECT_STREQ("opus", gcodec.plname);
1767 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768}
1769
1770// Test that we handle various ways of specifying bitrate.
1771TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001772 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001773 cricket::AudioSendParameters parameters;
1774 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001776 {
1777 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1778 EXPECT_EQ(103, gcodec.pltype);
1779 EXPECT_STREQ("ISAC", gcodec.plname);
1780 EXPECT_EQ(32000, gcodec.rate);
1781 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001782
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001783 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001784 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001785 {
1786 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1787 EXPECT_EQ(103, gcodec.pltype);
1788 EXPECT_STREQ("ISAC", gcodec.plname);
1789 EXPECT_EQ(-1, gcodec.rate);
1790 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001792 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001793 {
1794 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1795 EXPECT_EQ(103, gcodec.pltype);
1796 EXPECT_STREQ("ISAC", gcodec.plname);
1797 EXPECT_EQ(28000, gcodec.rate);
1798 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001799
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001801 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001802 {
1803 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1804 EXPECT_EQ(0, gcodec.pltype);
1805 EXPECT_STREQ("PCMU", gcodec.plname);
1806 EXPECT_EQ(64000, gcodec.rate);
1807 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001809 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001810 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001811 {
1812 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1813 EXPECT_EQ(0, gcodec.pltype);
1814 EXPECT_STREQ("PCMU", gcodec.plname);
1815 EXPECT_EQ(64000, gcodec.rate);
1816 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs[0] = kOpusCodec;
1819 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001821 {
1822 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1823 EXPECT_EQ(111, gcodec.pltype);
1824 EXPECT_STREQ("opus", gcodec.plname);
1825 EXPECT_EQ(32000, gcodec.rate);
1826 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827}
1828
Brave Yao5225dd82015-03-26 07:39:19 +08001829// Test that we could set packet size specified in kCodecParamPTime.
1830TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
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);
1834 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_EQ(1920, GetCodecPacSize(kSsrc1)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001837
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001839 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001840 EXPECT_EQ(480, GetCodecPacSize(kSsrc1)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001841
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001842 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001843 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001844 EXPECT_EQ(2880, GetCodecPacSize(kSsrc1)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001845
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001846 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1847 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001848 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001849 EXPECT_EQ(480, GetCodecPacSize(
1850 kSsrc1)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001851
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1853 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001854 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001855 EXPECT_EQ(640, GetCodecPacSize(
1856 kSsrc1)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001857}
1858
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001859// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001860TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001861 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001862 cricket::AudioSendParameters parameters;
1863 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001864}
1865
1866// Test that we can set send codecs even with telephone-event codec as the first
1867// one on the list.
1868TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001871 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001872 parameters.codecs.push_back(kIsacCodec);
1873 parameters.codecs.push_back(kPcmuCodec);
1874 parameters.codecs[0].id = 98; // DTMF
1875 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001877 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001878 EXPECT_EQ(96, gcodec.pltype);
1879 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001880 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001881}
1882
solenberg31642aa2016-03-14 08:00:37 -07001883// Test that payload type range is limited for telephone-event codec.
1884TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001885 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001886 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001887 parameters.codecs.push_back(kTelephoneEventCodec1);
solenberg31642aa2016-03-14 08:00:37 -07001888 parameters.codecs.push_back(kIsacCodec);
1889 parameters.codecs[0].id = 0; // DTMF
1890 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001892 EXPECT_TRUE(channel_->CanInsertDtmf());
1893 parameters.codecs[0].id = 128; // DTMF
1894 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1895 EXPECT_FALSE(channel_->CanInsertDtmf());
1896 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001898 EXPECT_TRUE(channel_->CanInsertDtmf());
1899 parameters.codecs[0].id = -1; // DTMF
1900 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1901 EXPECT_FALSE(channel_->CanInsertDtmf());
1902}
1903
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001904// Test that we can set send codecs even with CN codec as the first
1905// one on the list.
1906TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001907 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 cricket::AudioSendParameters parameters;
1909 parameters.codecs.push_back(kCn16000Codec);
1910 parameters.codecs.push_back(kIsacCodec);
1911 parameters.codecs.push_back(kPcmuCodec);
1912 parameters.codecs[0].id = 98; // wideband CN
1913 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001914 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001915 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1916 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1917 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1918 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
1919 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920}
1921
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001922// Test that we set VAD and DTMF types correctly as caller.
1923TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001924 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001925 cricket::AudioSendParameters parameters;
1926 parameters.codecs.push_back(kIsacCodec);
1927 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 parameters.codecs.push_back(kCn16000Codec);
1930 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001931 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 parameters.codecs[0].id = 96;
1933 parameters.codecs[2].id = 97; // wideband CN
1934 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001935 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001936 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1937 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1938 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1939 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
1940 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1941 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
1942 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001943 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944}
1945
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001946// Test that we set VAD and DTMF types correctly as callee.
1947TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001948 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 cricket::AudioSendParameters parameters;
1950 parameters.codecs.push_back(kIsacCodec);
1951 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001952 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 parameters.codecs.push_back(kCn16000Codec);
1954 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001955 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001956 parameters.codecs[0].id = 96;
1957 parameters.codecs[2].id = 97; // wideband CN
1958 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001960 EXPECT_TRUE(channel_->AddSendStream(
1961 cricket::StreamParams::CreateLegacy(kSsrc1)));
1962
minyue7a973442016-10-20 03:27:12 -07001963 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1964 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1965 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1966 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
1967 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1968 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
1969 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001970 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001971}
1972
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001973// Test that we only apply VAD if we have a CN codec that matches the
1974// send codec clockrate.
1975TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001976 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001978 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001979 parameters.codecs.push_back(kIsacCodec);
1980 parameters.codecs.push_back(kCn16000Codec);
1981 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001983 {
1984 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1985 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1986 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
1987 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1988 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
1989 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
1990 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001991 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001992 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001993 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001994 {
1995 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1996 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
1997 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1998 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001999 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002000 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002001 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002002 {
2003 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2004 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2005 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2006 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2007 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2008 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2009 }
Brave Yao5225dd82015-03-26 07:39:19 +08002010 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002012 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002013 {
2014 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2015 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2016 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2017 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002018}
2019
2020// Test that we perform case-insensitive matching of codec names.
2021TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002022 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002023 cricket::AudioSendParameters parameters;
2024 parameters.codecs.push_back(kIsacCodec);
2025 parameters.codecs.push_back(kPcmuCodec);
2026 parameters.codecs.push_back(kCn16000Codec);
2027 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002028 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002029 parameters.codecs[0].name = "iSaC";
2030 parameters.codecs[0].id = 96;
2031 parameters.codecs[2].id = 97; // wideband CN
2032 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002033 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002034 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2035 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2036 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2037 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2038 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2039 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2040 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002041 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002042}
2043
stefanba4c0e42016-02-04 04:12:24 -08002044class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2045 public:
2046 WebRtcVoiceEngineWithSendSideBweTest()
2047 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2048};
2049
2050TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2051 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002052 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002053 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002054 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2055 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2056 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002057 extension.id);
2058 return;
2059 }
2060 }
2061 FAIL() << "Transport sequence number extension not in header-extension list.";
2062}
2063
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002064// Test support for audio level header extension.
2065TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002066 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002067}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002068TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002069 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002070}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002071
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002072// Test support for absolute send time header extension.
2073TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002074 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAbsSendTimeUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002075}
2076TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002077 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAbsSendTimeUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002078}
2079
solenberg1ac56142015-10-13 03:58:19 -07002080// Test that we can create a channel and start sending on it.
2081TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002082 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(send_parameters_);
2084 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002085 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002086 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002087 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2088}
2089
2090// Test that a channel will send if and only if it has a source and is enabled
2091// for sending.
2092TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002093 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002094 SetSendParameters(send_parameters_);
2095 SetAudioSend(kSsrc1, true, nullptr);
2096 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002097 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002098 SetAudioSend(kSsrc1, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002099 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002100 SetAudioSend(kSsrc1, true, nullptr);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002101 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002102}
2103
solenberg94218532016-06-16 10:53:22 -07002104// Test that a channel is muted/unmuted.
2105TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2106 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002107 SetSendParameters(send_parameters_);
solenberg94218532016-06-16 10:53:22 -07002108 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002109 SetAudioSend(kSsrc1, true, nullptr);
solenberg94218532016-06-16 10:53:22 -07002110 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002111 SetAudioSend(kSsrc1, false, nullptr);
solenberg94218532016-06-16 10:53:22 -07002112 EXPECT_TRUE(GetSendStream(kSsrc1).muted());
2113}
2114
solenberg6d6e7c52016-04-13 09:07:30 -07002115// Test that SetSendParameters() does not alter a stream's send state.
2116TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2117 EXPECT_TRUE(SetupSendStream());
2118 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2119
2120 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002121 SetSend(true);
solenberg6d6e7c52016-04-13 09:07:30 -07002122 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2123
2124 // Changing RTP header extensions will recreate the AudioSendStream.
2125 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002126 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002127 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002128 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2129
2130 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002131 SetSend(false);
solenberg6d6e7c52016-04-13 09:07:30 -07002132 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2133
2134 // Changing RTP header extensions will recreate the AudioSendStream.
2135 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002136 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002137 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2138}
2139
solenberg1ac56142015-10-13 03:58:19 -07002140// Test that we can create a channel and start playing out on it.
2141TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002142 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002143 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002144 channel_->SetPlayout(true);
2145 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
2146 channel_->SetPlayout(false);
2147 EXPECT_FALSE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148}
2149
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150// Test that we can add and remove send streams.
2151TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2152 SetupForMultiSendStream();
2153
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002155 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156
solenbergc96df772015-10-21 13:01:53 -07002157 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002159 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002160 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002162 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
tfarina5237aaf2015-11-10 23:44:30 -08002164 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165
solenbergc96df772015-10-21 13:01:53 -07002166 // Delete the send streams.
2167 for (uint32_t ssrc : kSsrcs4) {
2168 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002169 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002170 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002171 }
solenbergc96df772015-10-21 13:01:53 -07002172 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173}
2174
2175// Test SetSendCodecs correctly configure the codecs in all send streams.
2176TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2177 SetupForMultiSendStream();
2178
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002181 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002182 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002185 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002186 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002187 parameters.codecs.push_back(kIsacCodec);
2188 parameters.codecs.push_back(kCn16000Codec);
2189 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002190 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002191
2192 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002193 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002194 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2195 const auto& send_codec_spec =
2196 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2197 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2198 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2199 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2200 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2201 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002202 }
2203
minyue7a973442016-10-20 03:27:12 -07002204 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002205 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002206 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002207 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002208 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2209 const auto& send_codec_spec =
2210 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2211 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2212 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2213 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2214 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 }
2216}
2217
2218// Test we can SetSend on all send streams correctly.
2219TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2220 SetupForMultiSendStream();
2221
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002222 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002223 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002225 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002226 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002227 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 }
2229
2230 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002231 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002232 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002233 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002234 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002235 }
2236
2237 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002238 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002239 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002240 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002241 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002242 }
2243}
2244
2245// Test we can set the correct statistics on all send streams.
2246TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2247 SetupForMultiSendStream();
2248
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002249 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002250 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002251 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002252 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002253 }
solenberg85a04962015-10-27 03:35:21 -07002254
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002255 // Create a receive stream to check that none of the send streams end up in
2256 // the receive stream stats.
solenberg8189b022016-06-14 12:13:00 -07002257 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg971cab02016-06-14 10:02:41 -07002258
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002259 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002260 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002261 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002262 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002263
solenberg85a04962015-10-27 03:35:21 -07002264 // Check stats for the added streams.
2265 {
2266 cricket::VoiceMediaInfo info;
2267 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002268
solenberg85a04962015-10-27 03:35:21 -07002269 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002270 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002271 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002272 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002273 }
2274
2275 // We have added one receive stream. We should see empty stats.
2276 EXPECT_EQ(info.receivers.size(), 1u);
2277 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002278 }
solenberg1ac56142015-10-13 03:58:19 -07002279
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002280 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002281 {
2282 cricket::VoiceMediaInfo info;
2283 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2284 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002285 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002286 EXPECT_EQ(0u, info.receivers.size());
2287 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002288
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002289 // Deliver a new packet - a default receive stream should be created and we
2290 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002291 {
2292 cricket::VoiceMediaInfo info;
2293 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2294 SetAudioReceiveStreamStats();
2295 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002296 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002297 EXPECT_EQ(1u, info.receivers.size());
2298 VerifyVoiceReceiverInfo(info.receivers[0]);
2299 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002300}
2301
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002302// Test that we can add and remove receive streams, and do proper send/playout.
2303// We can receive on multiple streams while sending one stream.
2304TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002305 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002306
solenberg1ac56142015-10-13 03:58:19 -07002307 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002308 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002309 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002310
solenberg1ac56142015-10-13 03:58:19 -07002311 // Adding another stream should enable playout on the new stream only.
solenberg8189b022016-06-14 12:13:00 -07002312 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002313 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002314 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002315
solenberg1ac56142015-10-13 03:58:19 -07002316 // Make sure only the new stream is played out.
aleloi84ef6152016-08-04 05:28:21 -07002317 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002318
2319 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg8189b022016-06-14 12:13:00 -07002320 EXPECT_TRUE(AddRecvStream(kSsrc3));
aleloi84ef6152016-08-04 05:28:21 -07002321 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2322 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323
2324 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002325 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002326 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002327
2328 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002329 channel_->SetPlayout(false);
2330 EXPECT_FALSE(GetRecvStream(kSsrc2).started());
2331 EXPECT_FALSE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002332
aleloi84ef6152016-08-04 05:28:21 -07002333 // Restart playout and make sure recv streams are played out.
2334 channel_->SetPlayout(true);
2335 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2336 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002337
aleloi84ef6152016-08-04 05:28:21 -07002338 // Now remove the recv streams.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002339 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2340 EXPECT_TRUE(channel_->RemoveRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002341}
2342
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002343// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002344// and start sending on it.
2345TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002346 EXPECT_TRUE(SetupSendStream());
solenberg246b8172015-12-08 09:50:23 -08002347 cricket::AudioOptions options_adjust_agc;
2348 options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349 webrtc::AgcConfig agc_config;
2350 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2351 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002352 send_parameters_.options = options_adjust_agc;
solenberg059fb442016-10-26 05:12:24 -07002353 SetSendParameters(send_parameters_);
2354 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002355 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002356 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2357 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
solenberg059fb442016-10-26 05:12:24 -07002358 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002359 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002360 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361}
2362
wu@webrtc.org97077a32013-10-25 21:18:33 +00002363TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002364 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002365 EXPECT_CALL(adm_,
2366 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
wu@webrtc.org97077a32013-10-25 21:18:33 +00002367 webrtc::AgcConfig agc_config;
2368 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2369 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002370 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2371 send_parameters_.options.tx_agc_digital_compression_gain =
2372 rtc::Optional<uint16_t>(9);
2373 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2374 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002375 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002376 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2377 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2378 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2379 EXPECT_TRUE(agc_config.limiterEnable);
2380
2381 // Check interaction with adjust_agc_delta. Both should be respected, for
2382 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002383 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg059fb442016-10-26 05:12:24 -07002384 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002385 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2386 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2387}
2388
wu@webrtc.org97077a32013-10-25 21:18:33 +00002389TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002390 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002391 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2392 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002393 send_parameters_.options.recording_sample_rate =
2394 rtc::Optional<uint32_t>(48000);
2395 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002396 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002397}
2398
minyue6b825df2016-10-31 04:08:32 -07002399TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2400 EXPECT_TRUE(SetupSendStream());
2401 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2402 send_parameters_.options.audio_network_adaptor_config =
2403 rtc::Optional<std::string>("1234");
2404 SetSendParameters(send_parameters_);
2405 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2406 GetAudioNetworkAdaptorConfig(kSsrc1));
2407}
2408
2409TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2410 EXPECT_TRUE(SetupSendStream());
2411 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2412 send_parameters_.options.audio_network_adaptor_config =
2413 rtc::Optional<std::string>("1234");
2414 SetSendParameters(send_parameters_);
2415 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2416 GetAudioNetworkAdaptorConfig(kSsrc1));
2417 const int initial_num = call_.GetNumCreatedSendStreams();
2418 cricket::AudioOptions options;
2419 options.audio_network_adaptor = rtc::Optional<bool>(false);
2420 SetAudioSend(kSsrc1, true, nullptr, &options);
2421 // AudioSendStream expected to be recreated.
2422 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
2423 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrc1));
2424}
2425
2426TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2427 EXPECT_TRUE(SetupSendStream());
2428 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2429 send_parameters_.options.audio_network_adaptor_config =
2430 rtc::Optional<std::string>("1234");
2431 SetSendParameters(send_parameters_);
2432 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2433 GetAudioNetworkAdaptorConfig(kSsrc1));
2434 const int initial_num = call_.GetNumCreatedSendStreams();
2435 cricket::AudioOptions options;
2436 options.audio_network_adaptor = rtc::Optional<bool>();
2437 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2438 // adaptor.
2439 SetAudioSend(kSsrc1, true, nullptr, &options);
2440 // AudioSendStream not expected to be recreated.
2441 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2442 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2443 GetAudioNetworkAdaptorConfig(kSsrc1));
2444}
2445
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002447// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002449 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002450 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451}
2452
2453TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2454 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002455 EXPECT_TRUE(SetupSendStream());
solenbergff976312016-03-30 23:28:51 -07002456 // SetupSendStream adds a send stream with kSsrc1, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002457 // stream has to use a different SSRC.
solenberg8189b022016-06-14 12:13:00 -07002458 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002459 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002460 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002461 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462
solenberg85a04962015-10-27 03:35:21 -07002463 // Check stats for the added streams.
2464 {
2465 cricket::VoiceMediaInfo info;
2466 EXPECT_EQ(true, channel_->GetStats(&info));
2467
2468 // We have added one send stream. We should see the stats we've set.
2469 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002470 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002471 // We have added one receive stream. We should see empty stats.
2472 EXPECT_EQ(info.receivers.size(), 1u);
2473 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2474 }
solenberg1ac56142015-10-13 03:58:19 -07002475
solenberg566ef242015-11-06 15:34:49 -08002476 // Start sending - this affects some reported stats.
2477 {
2478 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002479 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002480 EXPECT_EQ(true, channel_->GetStats(&info));
2481 VerifyVoiceSenderInfo(info.senders[0], true);
2482 }
2483
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002484 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002485 {
2486 cricket::VoiceMediaInfo info;
2487 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2488 EXPECT_EQ(true, channel_->GetStats(&info));
2489 EXPECT_EQ(1u, info.senders.size());
2490 EXPECT_EQ(0u, info.receivers.size());
2491 }
solenberg1ac56142015-10-13 03:58:19 -07002492
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002493 // Deliver a new packet - a default receive stream should be created and we
2494 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002495 {
2496 cricket::VoiceMediaInfo info;
2497 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2498 SetAudioReceiveStreamStats();
2499 EXPECT_EQ(true, channel_->GetStats(&info));
2500 EXPECT_EQ(1u, info.senders.size());
2501 EXPECT_EQ(1u, info.receivers.size());
2502 VerifyVoiceReceiverInfo(info.receivers[0]);
2503 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504}
2505
2506// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002507// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002509 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002510 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg8189b022016-06-14 12:13:00 -07002511 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -08002512 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513}
2514
2515// Test that the local SSRC is the same on sending and receiving channels if the
2516// receive channel is created before the send channel.
2517TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002518 EXPECT_TRUE(SetupChannel());
solenberg4a0f7b52016-06-16 13:07:33 -07002519 EXPECT_TRUE(AddRecvStream(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520 EXPECT_TRUE(channel_->AddSendStream(
solenberg4a0f7b52016-06-16 13:07:33 -07002521 cricket::StreamParams::CreateLegacy(kSsrc1)));
2522 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2523 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524}
2525
2526// Test that we can properly receive packets.
2527TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002528 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002529 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002530 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002531
2532 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2533 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534}
2535
2536// Test that we can properly receive packets on multiple streams.
2537TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002538 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002539 const uint32_t ssrc1 = 1;
2540 const uint32_t ssrc2 = 2;
2541 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002542 EXPECT_TRUE(AddRecvStream(ssrc1));
2543 EXPECT_TRUE(AddRecvStream(ssrc2));
2544 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002545 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002546 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002547 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002549 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 }
mflodman3d7db262016-04-29 00:57:13 -07002551
2552 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2553 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2554 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2555
2556 EXPECT_EQ(s1.received_packets(), 0);
2557 EXPECT_EQ(s2.received_packets(), 0);
2558 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002559
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_EQ(s1.received_packets(), 0);
2562 EXPECT_EQ(s2.received_packets(), 0);
2563 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002564
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002566 EXPECT_EQ(s1.received_packets(), 1);
2567 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2568 EXPECT_EQ(s2.received_packets(), 0);
2569 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002570
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002571 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_EQ(s1.received_packets(), 1);
2573 EXPECT_EQ(s2.received_packets(), 1);
2574 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2575 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002576
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002577 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002578 EXPECT_EQ(s1.received_packets(), 1);
2579 EXPECT_EQ(s2.received_packets(), 1);
2580 EXPECT_EQ(s3.received_packets(), 1);
2581 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002582
mflodman3d7db262016-04-29 00:57:13 -07002583 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2584 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2585 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002586}
2587
solenberg7e63ef02015-11-20 00:19:43 -08002588// Test that receiving on an unsignalled stream works (default channel will be
2589// created).
2590TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
solenbergff976312016-03-30 23:28:51 -07002591 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002592 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2593
solenberg7e63ef02015-11-20 00:19:43 -08002594 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002595
2596 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2597 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2598 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002599}
2600
2601// Test that receiving on an unsignalled stream works (default channel will be
2602// created), and that packets will be forwarded to the default channel
2603// regardless of their SSRCs.
2604TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
solenbergff976312016-03-30 23:28:51 -07002605 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002606 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002607 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2608
mflodman3d7db262016-04-29 00:57:13 -07002609 // Note that ssrc = 0 is not supported.
2610 uint32_t ssrc = 1;
2611 for (; ssrc < 10; ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002612 rtc::SetBE32(&packet[8], ssrc);
2613 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002614
2615 // Verify we only have one default stream.
2616 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2617 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2618 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002619 }
mflodman3d7db262016-04-29 00:57:13 -07002620
2621 // Sending the same ssrc again should not create a new stream.
2622 --ssrc;
2623 DeliverPacket(packet, sizeof(packet));
2624 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2625 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2626 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002627}
2628
2629// Test that a default channel is created even after a signalled stream has been
2630// added, and that this stream will get any packets for unknown SSRCs.
2631TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
solenbergff976312016-03-30 23:28:51 -07002632 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002633 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002634 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2635
2636 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002637 const uint32_t signaled_ssrc = 1;
2638 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002639 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002640 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002641 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2642 packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002643
2644 // Note that the first unknown SSRC cannot be 0, because we only support
2645 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002646 const uint32_t unsignaled_ssrc = 7011;
2647 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002648 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002649 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2650 packet, sizeof(packet)));
2651 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2652
2653 DeliverPacket(packet, sizeof(packet));
2654 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2655
2656 rtc::SetBE32(&packet[8], signaled_ssrc);
2657 DeliverPacket(packet, sizeof(packet));
2658 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2659 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002660}
2661
solenberg0a617e22015-10-20 15:49:38 -07002662// Test that we properly handle failures to add a receive stream.
2663TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002664 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002665 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002666 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667}
2668
solenberg0a617e22015-10-20 15:49:38 -07002669// Test that we properly handle failures to add a send stream.
2670TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002671 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002672 voe_.set_fail_create_channel(true);
2673 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2674}
2675
solenberg1ac56142015-10-13 03:58:19 -07002676// Test that AddRecvStream creates new stream.
2677TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002678 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002679 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002680 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002681 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002682}
2683
2684// Test that after adding a recv stream, we do not decode more codecs than
2685// those previously passed into SetRecvCodecs.
2686TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002687 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002688 cricket::AudioRecvParameters parameters;
2689 parameters.codecs.push_back(kIsacCodec);
2690 parameters.codecs.push_back(kPcmuCodec);
2691 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002692 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693 int channel_num2 = voe_.GetLastChannel();
2694 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002695 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002696 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002697 gcodec.channels = 2;
2698 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2699}
2700
2701// Test that we properly clean up any streams that were added, even if
2702// not explicitly removed.
2703TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002704 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002705 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002706 EXPECT_TRUE(AddRecvStream(1));
2707 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002708 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2709 delete channel_;
2710 channel_ = NULL;
2711 EXPECT_EQ(0, voe_.GetNumChannels());
2712}
2713
wu@webrtc.org78187522013-10-07 23:32:02 +00002714TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002715 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002716 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002717}
2718
2719TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002720 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002721 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002722 // Manually delete channel to simulate a failure.
2723 int channel = voe_.GetLastChannel();
2724 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2725 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002726 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002727 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002728 EXPECT_NE(channel, new_channel);
2729 // The last created channel is deleted too.
2730 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002731}
2732
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002733// Test the InsertDtmf on default send stream as caller.
2734TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2735 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002736}
2737
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002738// Test the InsertDtmf on default send stream as callee
2739TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2740 TestInsertDtmf(0, false);
2741}
2742
2743// Test the InsertDtmf on specified send stream as caller.
2744TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2745 TestInsertDtmf(kSsrc1, true);
2746}
2747
2748// Test the InsertDtmf on specified send stream as callee.
2749TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2750 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751}
2752
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002754 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002755 EXPECT_CALL(adm_,
2756 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2757 EXPECT_CALL(adm_,
2758 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2759 EXPECT_CALL(adm_,
2760 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761 bool ec_enabled;
2762 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002763 webrtc::AecmModes aecm_mode;
2764 bool cng_enabled;
2765 bool agc_enabled;
2766 webrtc::AgcModes agc_mode;
2767 webrtc::AgcConfig agc_config;
2768 bool ns_enabled;
2769 webrtc::NsModes ns_mode;
2770 bool highpass_filter_enabled;
2771 bool stereo_swapping_enabled;
2772 bool typing_detection_enabled;
2773 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774 voe_.GetAecmMode(aecm_mode, cng_enabled);
2775 voe_.GetAgcStatus(agc_enabled, agc_mode);
2776 voe_.GetAgcConfig(agc_config);
2777 voe_.GetNsStatus(ns_enabled, ns_mode);
2778 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2779 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2780 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2781 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002782 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783 EXPECT_FALSE(cng_enabled);
2784 EXPECT_TRUE(agc_enabled);
2785 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2786 EXPECT_TRUE(ns_enabled);
2787 EXPECT_TRUE(highpass_filter_enabled);
2788 EXPECT_FALSE(stereo_swapping_enabled);
2789 EXPECT_TRUE(typing_detection_enabled);
2790 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2791 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002792 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2793 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002794
solenberg246b8172015-12-08 09:50:23 -08002795 // Nothing set in AudioOptions, so everything should be as default.
2796 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002797 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002798 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799 voe_.GetAecmMode(aecm_mode, cng_enabled);
2800 voe_.GetAgcStatus(agc_enabled, agc_mode);
2801 voe_.GetAgcConfig(agc_config);
2802 voe_.GetNsStatus(ns_enabled, ns_mode);
2803 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2804 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2805 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2806 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002807 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002808 EXPECT_FALSE(cng_enabled);
2809 EXPECT_TRUE(agc_enabled);
2810 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2811 EXPECT_TRUE(ns_enabled);
2812 EXPECT_TRUE(highpass_filter_enabled);
2813 EXPECT_FALSE(stereo_swapping_enabled);
2814 EXPECT_TRUE(typing_detection_enabled);
2815 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2816 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002817 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2818 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002819
2820 // Turn echo cancellation off
solenberg246b8172015-12-08 09:50:23 -08002821 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002822 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823 voe_.GetEcStatus(ec_enabled, ec_mode);
2824 EXPECT_FALSE(ec_enabled);
2825
2826 // Turn echo cancellation back on, with settings, and make sure
2827 // nothing else changed.
solenberg246b8172015-12-08 09:50:23 -08002828 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831 voe_.GetAecmMode(aecm_mode, cng_enabled);
2832 voe_.GetAgcStatus(agc_enabled, agc_mode);
2833 voe_.GetAgcConfig(agc_config);
2834 voe_.GetNsStatus(ns_enabled, ns_mode);
2835 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2836 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2837 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2838 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002839 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840 EXPECT_TRUE(agc_enabled);
2841 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2842 EXPECT_TRUE(ns_enabled);
2843 EXPECT_TRUE(highpass_filter_enabled);
2844 EXPECT_FALSE(stereo_swapping_enabled);
2845 EXPECT_TRUE(typing_detection_enabled);
2846 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2847 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2848
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002849 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2850 // control.
solenberg246b8172015-12-08 09:50:23 -08002851 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002852 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002853 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002854 voe_.GetAecmMode(aecm_mode, cng_enabled);
2855 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002856 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002857 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2858
2859 // Turn off echo cancellation and delay agnostic aec.
solenberg246b8172015-12-08 09:50:23 -08002860 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2861 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2862 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002863 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002864 voe_.GetEcStatus(ec_enabled, ec_mode);
2865 EXPECT_FALSE(ec_enabled);
2866 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg246b8172015-12-08 09:50:23 -08002867 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002868 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002869 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002870 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002871 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002872 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2873
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874 // Turn off AGC
solenberg246b8172015-12-08 09:50:23 -08002875 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002876 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877 voe_.GetAgcStatus(agc_enabled, agc_mode);
2878 EXPECT_FALSE(agc_enabled);
2879
2880 // Turn AGC back on
solenberg246b8172015-12-08 09:50:23 -08002881 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2882 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002883 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884 voe_.GetAgcStatus(agc_enabled, agc_mode);
2885 EXPECT_TRUE(agc_enabled);
2886 voe_.GetAgcConfig(agc_config);
2887 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2888
2889 // Turn off other options (and stereo swapping on).
solenberg246b8172015-12-08 09:50:23 -08002890 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2891 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2892 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2893 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002894 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895 voe_.GetNsStatus(ns_enabled, ns_mode);
2896 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2897 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2898 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2899 EXPECT_FALSE(ns_enabled);
2900 EXPECT_FALSE(highpass_filter_enabled);
2901 EXPECT_FALSE(typing_detection_enabled);
2902 EXPECT_TRUE(stereo_swapping_enabled);
2903
solenberg1ac56142015-10-13 03:58:19 -07002904 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07002905 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906 voe_.GetEcStatus(ec_enabled, ec_mode);
2907 voe_.GetNsStatus(ns_enabled, ns_mode);
2908 EXPECT_TRUE(ec_enabled);
2909 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2910 EXPECT_FALSE(ns_enabled);
2911 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2912}
2913
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002914TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
solenbergff976312016-03-30 23:28:51 -07002915 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002916
2917 bool ec_enabled;
2918 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002919 bool agc_enabled;
2920 webrtc::AgcModes agc_mode;
2921 bool ns_enabled;
2922 webrtc::NsModes ns_mode;
2923 bool highpass_filter_enabled;
2924 bool stereo_swapping_enabled;
2925 bool typing_detection_enabled;
2926
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928 voe_.GetAgcStatus(agc_enabled, agc_mode);
2929 voe_.GetNsStatus(ns_enabled, ns_mode);
2930 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2931 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2932 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2933 EXPECT_TRUE(ec_enabled);
2934 EXPECT_TRUE(agc_enabled);
2935 EXPECT_TRUE(ns_enabled);
2936 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002937 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002939}
2940
2941TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2942 webrtc::AgcConfig set_config = {0};
2943 set_config.targetLeveldBOv = 3;
2944 set_config.digitalCompressionGaindB = 9;
2945 set_config.limiterEnable = true;
2946 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947
2948 webrtc::AgcConfig config = {0};
2949 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2950 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2951 EXPECT_EQ(set_config.digitalCompressionGaindB,
2952 config.digitalCompressionGaindB);
2953 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2954}
2955
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002958 EXPECT_CALL(adm_,
2959 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2960 EXPECT_CALL(adm_,
2961 BuiltInAGCIsAvailable()).Times(9).WillRepeatedly(Return(false));
2962 EXPECT_CALL(adm_,
2963 BuiltInNSIsAvailable()).Times(9).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002964 EXPECT_CALL(adm_,
2965 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2966 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2967 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
2968 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
2969 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002970
kwiberg686a8ef2016-02-26 03:00:35 -08002971 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002972 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002973 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002974 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002975 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002976 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977
2978 // Have to add a stream to make SetSend work.
2979 cricket::StreamParams stream1;
2980 stream1.ssrcs.push_back(1);
2981 channel1->AddSendStream(stream1);
2982 cricket::StreamParams stream2;
2983 stream2.ssrcs.push_back(2);
2984 channel2->AddSendStream(stream2);
2985
2986 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002987 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002988 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2989 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2990 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002991 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002992 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002993 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002994 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995
2996 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002997 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002998 parameters_options_no_ns.options.noise_suppression =
2999 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003000 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003002 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3003 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3004 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003005 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006
3007 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003008 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003009 parameters_options_no_agc.options.auto_gain_control =
3010 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003011 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003012 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3013 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3014 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003015 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003016
solenberg059fb442016-10-26 05:12:24 -07003017 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018 bool ec_enabled;
3019 webrtc::EcModes ec_mode;
3020 bool agc_enabled;
3021 webrtc::AgcModes agc_mode;
3022 bool ns_enabled;
3023 webrtc::NsModes ns_mode;
3024 voe_.GetEcStatus(ec_enabled, ec_mode);
3025 voe_.GetAgcStatus(agc_enabled, agc_mode);
3026 voe_.GetNsStatus(ns_enabled, ns_mode);
3027 EXPECT_TRUE(ec_enabled);
3028 EXPECT_TRUE(agc_enabled);
3029 EXPECT_TRUE(ns_enabled);
3030
solenberg059fb442016-10-26 05:12:24 -07003031 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032 voe_.GetEcStatus(ec_enabled, ec_mode);
3033 voe_.GetAgcStatus(agc_enabled, agc_mode);
3034 voe_.GetNsStatus(ns_enabled, ns_mode);
3035 EXPECT_TRUE(ec_enabled);
3036 EXPECT_TRUE(agc_enabled);
3037 EXPECT_FALSE(ns_enabled);
3038
solenberg059fb442016-10-26 05:12:24 -07003039 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003040 voe_.GetEcStatus(ec_enabled, ec_mode);
3041 voe_.GetAgcStatus(agc_enabled, agc_mode);
3042 voe_.GetNsStatus(ns_enabled, ns_mode);
3043 EXPECT_TRUE(ec_enabled);
3044 EXPECT_FALSE(agc_enabled);
3045 EXPECT_TRUE(ns_enabled);
3046
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047 // Make sure settings take effect while we are sending.
solenberg059fb442016-10-26 05:12:24 -07003048 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
3049 EXPECT_CALL(apm_, ApplyConfig(testing::_));
3050 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003051 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3052 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003053 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003054 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003055 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003056 rtc::Optional<bool>(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08003057 channel2->SetSend(true);
solenberg059fb442016-10-26 05:12:24 -07003058 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003059 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3060 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3061 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003062 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063 voe_.GetEcStatus(ec_enabled, ec_mode);
3064 voe_.GetAgcStatus(agc_enabled, agc_mode);
3065 voe_.GetNsStatus(ns_enabled, ns_mode);
3066 EXPECT_TRUE(ec_enabled);
3067 EXPECT_FALSE(agc_enabled);
3068 EXPECT_FALSE(ns_enabled);
3069}
3070
wu@webrtc.orgde305012013-10-31 15:40:38 +00003071// This test verifies DSCP settings are properly applied on voice media channel.
3072TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003073 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003074 cricket::FakeNetworkInterface network_interface;
3075 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003076 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003077
solenberg059fb442016-10-26 05:12:24 -07003078 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3079 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3080
solenbergbc37fc82016-04-04 09:54:44 -07003081 channel.reset(
3082 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003083 channel->SetInterface(&network_interface);
3084 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3085 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3086
3087 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003088 channel.reset(
3089 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003090 channel->SetInterface(&network_interface);
3091 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3092
3093 // Verify that setting the option to false resets the
3094 // DiffServCodePoint.
3095 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003096 channel.reset(
3097 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003098 channel->SetInterface(&network_interface);
3099 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3100 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3101
3102 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003103}
3104
solenberg1ac56142015-10-13 03:58:19 -07003105TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003106 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003107 cricket::WebRtcVoiceMediaChannel* media_channel =
3108 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003109 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003110 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003111 int channel_id = voe_.GetLastChannel();
3112 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3113 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003114 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003115 int channel_id2 = voe_.GetLastChannel();
3116 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003117}
3118
solenberg1ac56142015-10-13 03:58:19 -07003119TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003120 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003121 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003122 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3123 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3124 EXPECT_TRUE(channel_->AddSendStream(
3125 cricket::StreamParams::CreateLegacy(kSsrc1)));
3126 int channel_id = voe_.GetLastChannel();
3127 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3128 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3129 EXPECT_TRUE(channel_->AddSendStream(
3130 cricket::StreamParams::CreateLegacy(kSsrc2)));
3131 int channel_id2 = voe_.GetLastChannel();
3132 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003133}
3134
solenberg4bac9c52015-10-09 02:32:53 -07003135TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003136 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003137 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003138 cricket::StreamParams stream;
3139 stream.ssrcs.push_back(kSsrc2);
3140 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003141 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003142 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003143 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003144}
3145
3146TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003147 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003148 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3149 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003150 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003151 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003152 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3153 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3154 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003155}
3156
pbos8fc7fa72015-07-15 08:02:58 -07003157TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003158 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003159 const std::string kSyncLabel = "AvSyncLabel";
3160
solenbergff976312016-03-30 23:28:51 -07003161 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003162 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3163 sp.sync_label = kSyncLabel;
3164 // Creating two channels to make sure that sync label is set properly for both
3165 // the default voice channel and following ones.
3166 EXPECT_TRUE(channel_->AddRecvStream(sp));
3167 sp.ssrcs[0] += 1;
3168 EXPECT_TRUE(channel_->AddRecvStream(sp));
3169
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003170 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003171 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003172 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003173 << "SyncGroup should be set based on sync_label";
3174 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003175 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003176 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003177}
3178
solenberg3a941542015-11-16 07:34:50 -08003179// TODO(solenberg): Remove, once recv streams are configured through Call.
3180// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003181TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003182 // Test that setting the header extensions results in the expected state
3183 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003184 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003185 ssrcs.push_back(223);
3186 ssrcs.push_back(224);
3187
solenbergff976312016-03-30 23:28:51 -07003188 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003189 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003190 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003191 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003192 cricket::StreamParams::CreateLegacy(ssrc)));
3193 }
3194
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003195 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003196 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003197 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003198 EXPECT_NE(nullptr, s);
3199 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3200 }
3201
3202 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003203 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003204 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003205 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003206 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003207 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003208 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003209 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003210 EXPECT_NE(nullptr, s);
3211 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003212 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3213 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214 for (const auto& s_ext : s_exts) {
3215 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003216 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003217 }
3218 }
3219 }
3220 }
3221
3222 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003223 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003224 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003225 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003226 EXPECT_NE(nullptr, s);
3227 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3228 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229}
3230
3231TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3232 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003233 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003234 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003235 static const unsigned char kRtcp[] = {
3236 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3237 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3240 };
jbaucheec21bd2016-03-20 06:15:43 -07003241 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003242
solenbergff976312016-03-30 23:28:51 -07003243 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244 cricket::WebRtcVoiceMediaChannel* media_channel =
3245 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003246 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003247 EXPECT_TRUE(media_channel->AddRecvStream(
3248 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3249
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003250 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003251 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003252 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003253 EXPECT_EQ(0, s->received_packets());
3254 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3255 EXPECT_EQ(1, s->received_packets());
3256 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3257 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258}
Minyue2013aec2015-05-13 14:14:42 +02003259
solenberg0a617e22015-10-20 15:49:38 -07003260// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003261// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003262TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003263 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003264 EXPECT_TRUE(AddRecvStream(kSsrc2));
3265 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3266 EXPECT_TRUE(channel_->AddSendStream(
3267 cricket::StreamParams::CreateLegacy(kSsrc3)));
3268 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3269 EXPECT_TRUE(AddRecvStream(kSsrc4));
3270 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003271}
3272
solenberg7602aab2016-11-14 11:30:07 -08003273TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3274 EXPECT_TRUE(SetupRecvStream());
3275 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3276 EXPECT_TRUE(channel_->AddSendStream(
3277 cricket::StreamParams::CreateLegacy(kSsrc2)));
3278 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3279 EXPECT_TRUE(AddRecvStream(kSsrc3));
3280 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3281 EXPECT_TRUE(channel_->AddSendStream(
3282 cricket::StreamParams::CreateLegacy(kSsrc4)));
3283 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3284 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003285}
stefan658910c2015-09-03 05:48:32 -07003286
deadbeef884f5852016-01-15 09:20:04 -08003287TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003288 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003289 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3290 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003291
3292 // Setting the sink before a recv stream exists should do nothing.
3293 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003294 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003295 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3296
3297 // Now try actually setting the sink.
3298 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3299 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3300
3301 // Now try resetting it.
3302 channel_->SetRawAudioSink(kSsrc1, nullptr);
3303 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3304}
3305
3306TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003307 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003308 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3309 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003310
3311 // Should be able to set a default sink even when no stream exists.
3312 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3313
3314 // Create default channel and ensure it's assigned the default sink.
3315 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3316 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3317
3318 // Try resetting the default sink.
3319 channel_->SetRawAudioSink(0, nullptr);
3320 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3321
3322 // Try setting the default sink while the default stream exists.
3323 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3324 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3325
3326 // If we remove and add a default stream, it should get the same sink.
3327 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3328 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3329 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3330}
3331
skvlad7a43d252016-03-22 15:32:27 -07003332// Test that, just like the video channel, the voice channel communicates the
3333// network state to the call.
3334TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003335 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003336
3337 EXPECT_EQ(webrtc::kNetworkUp,
3338 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3339 EXPECT_EQ(webrtc::kNetworkUp,
3340 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3341
3342 channel_->OnReadyToSend(false);
3343 EXPECT_EQ(webrtc::kNetworkDown,
3344 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3345 EXPECT_EQ(webrtc::kNetworkUp,
3346 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3347
3348 channel_->OnReadyToSend(true);
3349 EXPECT_EQ(webrtc::kNetworkUp,
3350 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3351 EXPECT_EQ(webrtc::kNetworkUp,
3352 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3353}
3354
aleloi18e0b672016-10-04 02:45:47 -07003355// Test that playout is still started after changing parameters
3356TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3357 SetupRecvStream();
3358 channel_->SetPlayout(true);
3359 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3360
3361 // Changing RTP header extensions will recreate the AudioReceiveStream.
3362 cricket::AudioRecvParameters parameters;
3363 parameters.extensions.push_back(
3364 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3365 channel_->SetRecvParameters(parameters);
3366
3367 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3368}
3369
stefan658910c2015-09-03 05:48:32 -07003370// Tests that the library initializes and shuts down properly.
3371TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003372 // If the VoiceEngine wants to gather available codecs early, that's fine but
3373 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003374 cricket::WebRtcVoiceEngine engine(
3375 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory());
skvlad11a9cbf2016-10-07 11:53:05 -07003376 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003377 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003378 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003379 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3380 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003381 EXPECT_TRUE(channel != nullptr);
3382 delete channel;
solenbergff976312016-03-30 23:28:51 -07003383}
stefan658910c2015-09-03 05:48:32 -07003384
solenbergff976312016-03-30 23:28:51 -07003385// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003386TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3387 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3388 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3389 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003390 {
ossuc54071d2016-08-17 02:45:41 -07003391 cricket::WebRtcVoiceEngine engine(
3392 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory());
skvlad11a9cbf2016-10-07 11:53:05 -07003393 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003394 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003395 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003396 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3397 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3398 EXPECT_TRUE(channel != nullptr);
3399 delete channel;
3400 }
stefan658910c2015-09-03 05:48:32 -07003401}
3402
3403// Tests that the library is configured with the codecs we want.
3404TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003405 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3406 // module.
3407
stefan658910c2015-09-03 05:48:32 -07003408 // Check codecs by name.
solenberg26c8c912015-11-27 04:00:25 -08003409 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003410 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003411 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003412 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003413 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003414 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003415 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003416 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003417 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003418 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003419 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003420 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003421 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003422 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003423 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003424 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003425 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003426 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3427 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3428 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3429 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3430 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3431 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003432 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003433 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003434 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003435 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003436 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003437 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003438 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003439 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003440 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003441 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003442 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003443 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003444 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003445 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003446 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003447 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003448 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003449 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003450 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003451 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003452 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003453 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003454 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003455
stefan658910c2015-09-03 05:48:32 -07003456 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003457 // TODO(ossu): Why are the payload types of codecs with non-static payload
3458 // type assignments checked here? It shouldn't really matter.
3459 cricket::WebRtcVoiceEngine engine(
3460 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory());
solenberg2779bab2016-11-17 04:45:19 -08003461 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3462 if (codec.name == "CN" && codec.clockrate == 16000) {
3463 EXPECT_EQ(105, codec.id);
3464 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3465 EXPECT_EQ(106, codec.id);
3466 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3467 EXPECT_EQ(103, codec.id);
3468 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3469 EXPECT_EQ(104, codec.id);
3470 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3471 EXPECT_EQ(9, codec.id);
3472 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3473 EXPECT_EQ(126, codec.id);
3474 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3475 // Remove these checks once both send and receive side assigns payload types
3476 // dynamically.
3477 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3478 EXPECT_EQ(113, codec.id);
3479 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3480 EXPECT_EQ(112, codec.id);
3481 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3482 EXPECT_EQ(110, codec.id);
3483 } else if (codec.name == "opus") {
3484 EXPECT_EQ(111, codec.id);
3485 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3486 EXPECT_EQ("10", codec.params.find("minptime")->second);
3487 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3488 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003489 }
3490 }
stefan658910c2015-09-03 05:48:32 -07003491}
3492
3493// Tests that VoE supports at least 32 channels
3494TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003495 cricket::WebRtcVoiceEngine engine(
3496 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory());
skvlad11a9cbf2016-10-07 11:53:05 -07003497 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003498 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003499 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003500
3501 cricket::VoiceMediaChannel* channels[32];
3502 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003503 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003504 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3505 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003506 if (!channel)
3507 break;
stefan658910c2015-09-03 05:48:32 -07003508 channels[num_channels++] = channel;
3509 }
3510
tfarina5237aaf2015-11-10 23:44:30 -08003511 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003512 EXPECT_EQ(expected, num_channels);
3513
3514 while (num_channels > 0) {
3515 delete channels[--num_channels];
3516 }
stefan658910c2015-09-03 05:48:32 -07003517}
3518
3519// Test that we set our preferred codecs properly.
3520TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003521 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3522 // - Check that our builtin codecs are usable by Channel.
3523 // - The codecs provided by the engine is usable by Channel.
3524 // It does not check that the codecs in the RecvParameters are actually
3525 // what we sent in - though it's probably reasonable to expect so, if
3526 // SetRecvParameters returns true.
3527 // I think it will become clear once audio decoder injection is completed.
3528 cricket::WebRtcVoiceEngine engine(
3529 nullptr, webrtc::CreateBuiltinAudioDecoderFactory());
skvlad11a9cbf2016-10-07 11:53:05 -07003530 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003531 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003532 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003533 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3534 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003535 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003536 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003537 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003538}