blob: b655a49922734dc4dc9e0ec98e90d6e8b185160f [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"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
stefanba4c0e42016-02-04 04:12:24 -080018#include "webrtc/test/field_trial.h"
skvlad11a9cbf2016-10-07 11:53:05 -070019#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080020#include "webrtc/media/base/fakemediaengine.h"
21#include "webrtc/media/base/fakenetworkinterface.h"
22#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080023#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010024#include "webrtc/media/engine/fakewebrtccall.h"
25#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
26#include "webrtc/media/engine/webrtcvoiceengine.h"
ossu29b1a8d2016-06-13 07:34:51 -070027#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
28#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070029#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070030#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031
solenbergbc37fc82016-04-04 09:54:44 -070032using testing::Return;
33using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000034
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020035namespace {
36
deadbeef67cf2c12016-04-13 10:07:16 -070037const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
38const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
39const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
40const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
41const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070042const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
43const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080044const cricket::AudioCodec
45 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
46const cricket::AudioCodec
47 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
48
solenberg85a04962015-10-27 03:35:21 -070049const uint32_t kSsrc1 = 0x99;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080050const uint32_t kSsrc2 = 2;
51const uint32_t kSsrc3 = 3;
solenberg7602aab2016-11-14 11:30:07 -080052const uint32_t kSsrc4 = 0x42;
solenberg85a04962015-10-27 03:35:21 -070053const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
solenberg971cab02016-06-14 10:02:41 -070055constexpr int kRtpHistoryMs = 5000;
56
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057class FakeVoEWrapper : public cricket::VoEWrapper {
58 public:
59 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
60 : cricket::VoEWrapper(engine, // processing
61 engine, // base
62 engine, // codec
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063 engine, // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 engine) { // volume
65 }
66};
skvlad11a9cbf2016-10-07 11:53:05 -070067
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020068} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
solenbergff976312016-03-30 23:28:51 -070070// Tests that our stub library "works".
71TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070072 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
73 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
74 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070075 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
76 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
77 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -070078 StrictMock<webrtc::test::MockAudioProcessing> apm;
79 EXPECT_CALL(apm, ApplyConfig(testing::_));
80 EXPECT_CALL(apm, SetExtraOptions(testing::_));
81 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
82 cricket::FakeWebRtcVoiceEngine voe(&apm);
solenbergff976312016-03-30 23:28:51 -070083 EXPECT_FALSE(voe.IsInited());
84 {
ossuc54071d2016-08-17 02:45:41 -070085 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -080086 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -070087 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -070088 EXPECT_TRUE(voe.IsInited());
89 }
90 EXPECT_FALSE(voe.IsInited());
91}
92
deadbeef884f5852016-01-15 09:20:04 -080093class FakeAudioSink : public webrtc::AudioSinkInterface {
94 public:
95 void OnData(const Data& audio) override {}
96};
97
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080098class FakeAudioSource : public cricket::AudioSource {
99 void SetSink(Sink* sink) override {}
100};
101
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102class WebRtcVoiceEngineTestFake : public testing::Test {
103 public:
stefanba4c0e42016-02-04 04:12:24 -0800104 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
105
106 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg059fb442016-10-26 05:12:24 -0700107 : call_(webrtc::Call::Config(&event_log_)), voe_(&apm_),
skvlad11a9cbf2016-10-07 11:53:05 -0700108 override_field_trials_(field_trials) {
solenbergbc37fc82016-04-04 09:54:44 -0700109 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
110 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700111 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -0700114 EXPECT_CALL(apm_, ApplyConfig(testing::_));
115 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
116 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800117 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
118 // the tests here probe the specific set of codecs provided by the builtin
119 // factory. Those tests should probably be moved elsewhere.
120 engine_.reset(new cricket::WebRtcVoiceEngine(
121 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
122 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200123 send_parameters_.codecs.push_back(kPcmuCodec);
124 recv_parameters_.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000125 }
solenberg8189b022016-06-14 12:13:00 -0700126
solenbergff976312016-03-30 23:28:51 -0700127 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700128 EXPECT_CALL(apm_, ApplyConfig(testing::_));
129 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700130 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
131 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200132 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000133 }
solenberg8189b022016-06-14 12:13:00 -0700134
solenbergff976312016-03-30 23:28:51 -0700135 bool SetupRecvStream() {
136 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700137 return false;
138 }
solenberg8189b022016-06-14 12:13:00 -0700139 return AddRecvStream(kSsrc1);
solenberg1ac56142015-10-13 03:58:19 -0700140 }
solenberg8189b022016-06-14 12:13:00 -0700141
solenbergff976312016-03-30 23:28:51 -0700142 bool SetupSendStream() {
143 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000144 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 }
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800146 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1))) {
147 return false;
148 }
solenberg059fb442016-10-26 05:12:24 -0700149 EXPECT_CALL(apm_, set_output_will_be_muted(false));
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800150 return channel_->SetAudioSend(kSsrc1, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 }
solenberg8189b022016-06-14 12:13:00 -0700152
153 bool AddRecvStream(uint32_t ssrc) {
154 EXPECT_TRUE(channel_);
155 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
156 }
157
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000158 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700159 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700160 // Remove stream added in Setup.
solenberg3a941542015-11-16 07:34:50 -0800161 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg85a04962015-10-27 03:35:21 -0700162 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
solenberg0a617e22015-10-20 15:49:38 -0700163 // Verify the channel does not exist.
solenberg3a941542015-11-16 07:34:50 -0800164 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000165 }
solenberg8189b022016-06-14 12:13:00 -0700166
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700168 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000169 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000170 }
solenberg8189b022016-06-14 12:13:00 -0700171
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200172 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 }
175
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100176 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
177 const auto* send_stream = call_.GetAudioSendStream(ssrc);
178 EXPECT_TRUE(send_stream);
179 return *send_stream;
180 }
181
deadbeef884f5852016-01-15 09:20:04 -0800182 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
183 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
184 EXPECT_TRUE(recv_stream);
185 return *recv_stream;
186 }
187
solenberg3a941542015-11-16 07:34:50 -0800188 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800189 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800190 }
191
solenberg7add0582015-11-20 09:59:34 -0800192 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800193 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800194 }
195
solenberg059fb442016-10-26 05:12:24 -0700196 void SetSend(bool enable) {
197 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700198 if (enable) {
199 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
200 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
201 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700202 EXPECT_CALL(apm_, ApplyConfig(testing::_));
203 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700204 }
solenberg059fb442016-10-26 05:12:24 -0700205 channel_->SetSend(enable);
206 }
207
208 void SetSendParameters(const cricket::AudioSendParameters& params) {
209 EXPECT_CALL(apm_, ApplyConfig(testing::_));
210 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
211 ASSERT_TRUE(channel_);
212 EXPECT_TRUE(channel_->SetSendParameters(params));
213 }
214
minyue6b825df2016-10-31 04:08:32 -0700215 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
216 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700217 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
218 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700219 if (enable && options) {
220 EXPECT_CALL(apm_, ApplyConfig(testing::_));
221 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
222 }
223 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700224 }
225
solenbergffbbcac2016-11-17 05:25:37 -0800226 void TestInsertDtmf(uint32_t ssrc, bool caller,
227 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700228 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000229 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700230 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000231 // send stream.
232 EXPECT_TRUE(channel_->AddSendStream(
233 cricket::StreamParams::CreateLegacy(kSsrc1)));
234 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000235
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700237 SetSendParameters(send_parameters_);
238 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800240 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800241 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700242 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000244
245 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700246 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800247 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000248 EXPECT_TRUE(channel_->AddSendStream(
249 cricket::StreamParams::CreateLegacy(kSsrc1)));
250 }
251
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800253 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100255 // Test send.
256 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
257 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
258 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800259 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100260 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800261 EXPECT_EQ(codec.id, telephone_event.payload_type);
262 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100263 EXPECT_EQ(2, telephone_event.event_code);
264 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000265 }
266
267 // Test that send bandwidth is set correctly.
268 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000269 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
270 // |expected_result| is the expected result from SetMaxSendBandwidth().
271 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700272 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
273 int max_bitrate,
274 bool expected_result,
275 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200276 cricket::AudioSendParameters parameters;
277 parameters.codecs.push_back(codec);
278 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700279 if (expected_result) {
280 SetSendParameters(parameters);
281 } else {
282 EXPECT_FALSE(channel_->SetSendParameters(parameters));
283 }
minyue7a973442016-10-20 03:27:12 -0700284 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 }
286
skvlade0d46372016-04-07 22:59:22 -0700287 // Sets the per-stream maximum bitrate limit for the specified SSRC.
288 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700289 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700290 EXPECT_EQ(1UL, parameters.encodings.size());
291
deadbeefe702b302017-02-04 12:09:01 -0800292 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700293 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700294 }
295
solenberg059fb442016-10-26 05:12:24 -0700296 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700297 cricket::AudioSendParameters send_parameters;
298 send_parameters.codecs.push_back(codec);
299 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700300 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700301 }
302
minyue7a973442016-10-20 03:27:12 -0700303 void CheckSendCodec(int32_t ssrc,
304 const char expected_name[],
305 int expected_channels,
306 int expected_bitrate) {
307 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
308 EXPECT_STREQ(expected_name, codec.plname);
309 EXPECT_EQ(expected_channels, codec.channels);
310 EXPECT_EQ(expected_bitrate, codec.rate);
311 }
312
313 int GetOpusMaxPlaybackRate(int32_t ssrc) {
314 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
315 }
316
317 bool GetOpusDtx(int32_t ssrc) {
318 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
319 }
320
321 bool GetCodecFec(int32_t ssrc) {
322 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
323 }
324
skvlade0d46372016-04-07 22:59:22 -0700325 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700326 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
327 }
328
329 int GetCodecPacSize(int32_t ssrc) {
330 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700331 }
332
minyue6b825df2016-10-31 04:08:32 -0700333 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
334 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
335 }
336
skvlade0d46372016-04-07 22:59:22 -0700337 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
338 int global_max,
339 int stream_max,
340 bool expected_result,
341 int expected_codec_bitrate) {
342 // Clear the bitrate limit from the previous test case.
343 EXPECT_TRUE(SetMaxBitrateForStream(kSsrc1, -1));
344
345 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700346 SetGlobalMaxBitrate(codec, global_max);
skvlade0d46372016-04-07 22:59:22 -0700347 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrc1, stream_max));
348
349 // Verify that reading back the parameters gives results
350 // consistent with the Set() result.
351 webrtc::RtpParameters resulting_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700352 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -0700353 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
354 EXPECT_EQ(expected_result ? stream_max : -1,
355 resulting_parameters.encodings[0].max_bitrate_bps);
356
357 // Verify that the codec settings have the expected bitrate.
358 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrc1));
359 }
360
stefan13f1a0a2016-11-30 07:22:58 -0800361 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
362 int expected_min_bitrate_bps,
363 const char* start_bitrate_kbps,
364 int expected_start_bitrate_bps,
365 const char* max_bitrate_kbps,
366 int expected_max_bitrate_bps) {
367 EXPECT_TRUE(SetupSendStream());
368 auto& codecs = send_parameters_.codecs;
369 codecs.clear();
370 codecs.push_back(kOpusCodec);
371 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
372 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
373 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
374 SetSendParameters(send_parameters_);
375
376 EXPECT_EQ(expected_min_bitrate_bps,
377 call_.GetConfig().bitrate_config.min_bitrate_bps);
378 EXPECT_EQ(expected_start_bitrate_bps,
379 call_.GetConfig().bitrate_config.start_bitrate_bps);
380 EXPECT_EQ(expected_max_bitrate_bps,
381 call_.GetConfig().bitrate_config.max_bitrate_bps);
382 }
383
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000384 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700385 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000386
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000387 // Ensure extensions are off by default.
solenberg3a941542015-11-16 07:34:50 -0800388 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000389
390 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700391 send_parameters_.extensions.push_back(
392 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700393 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800394 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000395
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000396 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200397 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700398 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800399 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000400
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000401 // Ensure extension is set properly.
402 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700403 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700404 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800405 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700406 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800407 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000408
solenberg7add0582015-11-20 09:59:34 -0800409 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000410 EXPECT_TRUE(channel_->AddSendStream(
solenberg0a617e22015-10-20 15:49:38 -0700411 cricket::StreamParams::CreateLegacy(kSsrc2)));
solenberg3a941542015-11-16 07:34:50 -0800412 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
413 call_.GetAudioSendStream(kSsrc2));
414 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700415 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800416 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000417
418 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200419 send_parameters_.codecs.push_back(kPcmuCodec);
420 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700421 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800422 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
423 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000424 }
425
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000426 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700427 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000428
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000429 // Ensure extensions are off by default.
solenberg7add0582015-11-20 09:59:34 -0800430 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000431
432 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700433 recv_parameters_.extensions.push_back(
434 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800435 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
436 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000437
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000438 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800439 recv_parameters_.extensions.clear();
440 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
441 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000442
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000443 // Ensure extension is set properly.
444 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700445 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800446 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
447 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700448 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800449 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450
solenberg7add0582015-11-20 09:59:34 -0800451 // Ensure extension is set properly on new stream.
solenberg8189b022016-06-14 12:13:00 -0700452 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -0800453 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
454 call_.GetAudioReceiveStream(kSsrc2));
455 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700456 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800457 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000458
459 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800460 recv_parameters_.extensions.clear();
461 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
462 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
463 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000464 }
465
solenberg85a04962015-10-27 03:35:21 -0700466 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
467 webrtc::AudioSendStream::Stats stats;
468 stats.local_ssrc = 12;
469 stats.bytes_sent = 345;
470 stats.packets_sent = 678;
471 stats.packets_lost = 9012;
472 stats.fraction_lost = 34.56f;
473 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800474 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700475 stats.ext_seqnum = 789;
476 stats.jitter_ms = 12;
477 stats.rtt_ms = 345;
478 stats.audio_level = 678;
479 stats.aec_quality_min = 9.01f;
480 stats.echo_delay_median_ms = 234;
481 stats.echo_delay_std_ms = 567;
482 stats.echo_return_loss = 890;
483 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700484 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800485 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700486 stats.typing_noise_detected = true;
487 return stats;
488 }
489 void SetAudioSendStreamStats() {
490 for (auto* s : call_.GetAudioSendStreams()) {
491 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200492 }
solenberg85a04962015-10-27 03:35:21 -0700493 }
solenberg566ef242015-11-06 15:34:49 -0800494 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
495 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700496 const auto stats = GetAudioSendStreamStats();
497 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
498 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
499 EXPECT_EQ(info.packets_sent, stats.packets_sent);
500 EXPECT_EQ(info.packets_lost, stats.packets_lost);
501 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
502 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800503 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700504 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
505 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
506 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
507 EXPECT_EQ(info.audio_level, stats.audio_level);
508 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
509 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
510 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
511 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
512 EXPECT_EQ(info.echo_return_loss_enhancement,
513 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700514 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800515 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
516 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800517 EXPECT_EQ(info.typing_noise_detected,
518 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700519 }
520
521 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
522 webrtc::AudioReceiveStream::Stats stats;
523 stats.remote_ssrc = 123;
524 stats.bytes_rcvd = 456;
525 stats.packets_rcvd = 768;
526 stats.packets_lost = 101;
527 stats.fraction_lost = 23.45f;
528 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800529 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700530 stats.ext_seqnum = 678;
531 stats.jitter_ms = 901;
532 stats.jitter_buffer_ms = 234;
533 stats.jitter_buffer_preferred_ms = 567;
534 stats.delay_estimate_ms = 890;
535 stats.audio_level = 1234;
536 stats.expand_rate = 5.67f;
537 stats.speech_expand_rate = 8.90f;
538 stats.secondary_decoded_rate = 1.23f;
539 stats.accelerate_rate = 4.56f;
540 stats.preemptive_expand_rate = 7.89f;
541 stats.decoding_calls_to_silence_generator = 12;
542 stats.decoding_calls_to_neteq = 345;
543 stats.decoding_normal = 67890;
544 stats.decoding_plc = 1234;
545 stats.decoding_cng = 5678;
546 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700547 stats.decoding_muted_output = 3456;
548 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200549 return stats;
550 }
551 void SetAudioReceiveStreamStats() {
552 for (auto* s : call_.GetAudioReceiveStreams()) {
553 s->SetStats(GetAudioReceiveStreamStats());
554 }
555 }
556 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700557 const auto stats = GetAudioReceiveStreamStats();
558 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
559 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
560 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
561 EXPECT_EQ(info.packets_lost, stats.packets_lost);
562 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
563 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800564 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700565 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
566 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
567 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200568 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700569 stats.jitter_buffer_preferred_ms);
570 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
571 EXPECT_EQ(info.audio_level, stats.audio_level);
572 EXPECT_EQ(info.expand_rate, stats.expand_rate);
573 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
574 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
575 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
576 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200577 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700578 stats.decoding_calls_to_silence_generator);
579 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
580 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
581 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
582 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
583 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700584 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700585 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200586 }
hbos1acfbd22016-11-17 23:43:29 -0800587 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
588 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
589 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
590 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
591 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
592 codec.ToCodecParameters());
593 }
594 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
595 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
596 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
597 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
598 codec.ToCodecParameters());
599 }
600 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200601
peah8271d042016-11-22 07:24:52 -0800602 bool IsHighPassFilterEnabled() {
603 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
604 }
605
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000606 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700607 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700608 StrictMock<webrtc::test::MockAudioProcessing> apm_;
skvlad11a9cbf2016-10-07 11:53:05 -0700609 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200610 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000611 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700612 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700613 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200614 cricket::AudioSendParameters send_parameters_;
615 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800616 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800617 private:
618 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619};
620
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000621// Tests that we can create and destroy a channel.
622TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700623 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624}
625
solenberg31fec402016-05-06 02:13:12 -0700626// Test that we can add a send stream and that it has the correct defaults.
627TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
628 EXPECT_TRUE(SetupChannel());
629 EXPECT_TRUE(
630 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
631 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrc1);
632 EXPECT_EQ(kSsrc1, config.rtp.ssrc);
633 EXPECT_EQ("", config.rtp.c_name);
634 EXPECT_EQ(0u, config.rtp.extensions.size());
635 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
636 config.send_transport);
637}
638
639// Test that we can add a receive stream and that it has the correct defaults.
640TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
641 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -0700642 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg31fec402016-05-06 02:13:12 -0700643 const webrtc::AudioReceiveStream::Config& config =
644 GetRecvStreamConfig(kSsrc1);
645 EXPECT_EQ(kSsrc1, config.rtp.remote_ssrc);
646 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
647 EXPECT_FALSE(config.rtp.transport_cc);
648 EXPECT_EQ(0u, config.rtp.extensions.size());
649 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
650 config.rtcp_send_transport);
651 EXPECT_EQ("", config.sync_group);
652}
653
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700655// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700656// TODO(ossu): This test should move into a separate builtin audio codecs
657// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700658TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700659 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000660 ASSERT_FALSE(codecs.empty());
661 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
662 EXPECT_EQ(48000, codecs[0].clockrate);
663 EXPECT_EQ(2, codecs[0].channels);
664 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665}
666
stefanba4c0e42016-02-04 04:12:24 -0800667TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700668 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800669 bool opus_found = false;
670 for (cricket::AudioCodec codec : codecs) {
671 if (codec.name == "opus") {
672 EXPECT_TRUE(HasTransportCc(codec));
673 opus_found = true;
674 }
675 }
676 EXPECT_TRUE(opus_found);
677}
678
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679// Tests that we can find codecs by name or id, and that we interpret the
680// clockrate and bitrate fields properly.
681TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
682 cricket::AudioCodec codec;
683 webrtc::CodecInst codec_inst;
684 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800685 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800687 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800689 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
690 &codec_inst));
691 // Find telephone-event with explicit clockrate and 0 bitrate.
692 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800693 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 // Find ISAC with a different payload id.
695 codec = kIsacCodec;
696 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800697 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 EXPECT_EQ(codec.id, codec_inst.pltype);
699 // Find PCMU with a 0 clockrate.
700 codec = kPcmuCodec;
701 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800702 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 EXPECT_EQ(codec.id, codec_inst.pltype);
704 EXPECT_EQ(8000, codec_inst.plfreq);
705 // Find PCMU with a 0 bitrate.
706 codec = kPcmuCodec;
707 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800708 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 EXPECT_EQ(codec.id, codec_inst.pltype);
710 EXPECT_EQ(64000, codec_inst.rate);
711 // Find ISAC with an explicit bitrate.
712 codec = kIsacCodec;
713 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800714 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 EXPECT_EQ(codec.id, codec_inst.pltype);
716 EXPECT_EQ(32000, codec_inst.rate);
717}
718
719// Test that we set our inbound codecs properly, including changing PT.
720TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700721 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200722 cricket::AudioRecvParameters parameters;
723 parameters.codecs.push_back(kIsacCodec);
724 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800725 parameters.codecs.push_back(kTelephoneEventCodec1);
726 parameters.codecs.push_back(kTelephoneEventCodec2);
727 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200728 parameters.codecs[2].id = 126;
729 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700730 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700731 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800732
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800734 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735 gcodec.plfreq = 16000;
736 gcodec.channels = 1;
737 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
738 EXPECT_EQ(106, gcodec.pltype);
739 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800740
tfarina5237aaf2015-11-10 23:44:30 -0800741 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742 gcodec.plfreq = 8000;
743 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
744 EXPECT_EQ(126, gcodec.pltype);
745 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800746
747 gcodec.plfreq = 32000;
748 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
749 EXPECT_EQ(107, gcodec.pltype);
750 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751}
752
753// Test that we fail to set an unknown inbound codec.
754TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700755 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200756 cricket::AudioRecvParameters parameters;
757 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700758 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200759 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760}
761
762// Test that we fail if we have duplicate types in the inbound list.
763TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700764 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200765 cricket::AudioRecvParameters parameters;
766 parameters.codecs.push_back(kIsacCodec);
767 parameters.codecs.push_back(kCn16000Codec);
768 parameters.codecs[1].id = kIsacCodec.id;
769 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770}
771
772// Test that we can decode OPUS without stereo parameters.
773TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700774 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioRecvParameters parameters;
776 parameters.codecs.push_back(kIsacCodec);
777 parameters.codecs.push_back(kPcmuCodec);
778 parameters.codecs.push_back(kOpusCodec);
779 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700780 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700781 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800783 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784 // Even without stereo parameters, recv codecs still specify channels = 2.
785 EXPECT_EQ(2, opus.channels);
786 EXPECT_EQ(111, opus.pltype);
787 EXPECT_STREQ("opus", opus.plname);
788 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700789 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 EXPECT_EQ(111, opus.pltype);
791}
792
793// Test that we can decode OPUS with stereo = 0.
794TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700795 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 cricket::AudioRecvParameters parameters;
797 parameters.codecs.push_back(kIsacCodec);
798 parameters.codecs.push_back(kPcmuCodec);
799 parameters.codecs.push_back(kOpusCodec);
800 parameters.codecs[2].params["stereo"] = "0";
801 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700802 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803 int channel_num2 = voe_.GetLastChannel();
804 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800805 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 // Even when stereo is off, recv codecs still specify channels = 2.
807 EXPECT_EQ(2, opus.channels);
808 EXPECT_EQ(111, opus.pltype);
809 EXPECT_STREQ("opus", opus.plname);
810 opus.pltype = 0;
811 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
812 EXPECT_EQ(111, opus.pltype);
813}
814
815// Test that we can decode OPUS with stereo = 1.
816TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 cricket::AudioRecvParameters parameters;
819 parameters.codecs.push_back(kIsacCodec);
820 parameters.codecs.push_back(kPcmuCodec);
821 parameters.codecs.push_back(kOpusCodec);
822 parameters.codecs[2].params["stereo"] = "1";
823 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700824 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825 int channel_num2 = voe_.GetLastChannel();
826 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800827 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 EXPECT_EQ(2, opus.channels);
829 EXPECT_EQ(111, opus.pltype);
830 EXPECT_STREQ("opus", opus.plname);
831 opus.pltype = 0;
832 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
833 EXPECT_EQ(111, opus.pltype);
834}
835
836// Test that changes to recv codecs are applied to all streams.
837TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700838 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200839 cricket::AudioRecvParameters parameters;
840 parameters.codecs.push_back(kIsacCodec);
841 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800842 parameters.codecs.push_back(kTelephoneEventCodec1);
843 parameters.codecs.push_back(kTelephoneEventCodec2);
844 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 parameters.codecs[2].id = 126;
846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700847 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800849
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800851 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852 gcodec.plfreq = 16000;
853 gcodec.channels = 1;
854 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
855 EXPECT_EQ(106, gcodec.pltype);
856 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800857
tfarina5237aaf2015-11-10 23:44:30 -0800858 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859 gcodec.plfreq = 8000;
860 gcodec.channels = 1;
861 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
862 EXPECT_EQ(126, gcodec.pltype);
863 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800864
865 gcodec.plfreq = 32000;
866 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
867 EXPECT_EQ(107, gcodec.pltype);
868 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869}
870
871TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700872 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200873 cricket::AudioRecvParameters parameters;
874 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800875 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200876 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877
kwibergd32bf752017-01-19 07:03:59 -0800878 const auto& dm = GetRecvStreamConfig(kSsrc1).decoder_map;
879 ASSERT_EQ(1, dm.count(106));
880 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881}
882
883// Test that we can apply the same set of codecs again while playing.
884TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700885 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200886 cricket::AudioRecvParameters parameters;
887 parameters.codecs.push_back(kIsacCodec);
888 parameters.codecs.push_back(kCn16000Codec);
889 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700890 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200891 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892
893 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 parameters.codecs[0].id = 127;
895 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700896 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897}
898
899// Test that we can add a codec while playing.
900TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700901 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 cricket::AudioRecvParameters parameters;
903 parameters.codecs.push_back(kIsacCodec);
904 parameters.codecs.push_back(kCn16000Codec);
905 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700906 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 parameters.codecs.push_back(kOpusCodec);
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700910 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800912 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
914}
915
916TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700917 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000919 // Test that when autobw is enabled, bitrate is kept as the default
920 // value. autobw is enabled for the following tests because the target
921 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922
923 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700924 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925
926 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700927 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700930 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931}
932
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000933TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700934 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000936 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
938 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700939 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
940 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
941 // Rates above the max (56000) should be capped.
942 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
946 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
947 // Rates above the max (510000) should be capped.
948 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000953
954 // Test that we can only set a maximum bitrate for a fixed-rate codec
955 // if it's bigger than the fixed rate.
956
957 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
959 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
960 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
961 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
962 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
963 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
964 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000965}
966
967TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200969 const int kDesiredBitrate = 128000;
970 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700971 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200972 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700973 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000974
975 EXPECT_TRUE(channel_->AddSendStream(
976 cricket::StreamParams::CreateLegacy(kSsrc1)));
977
minyue7a973442016-10-20 03:27:12 -0700978 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrc1));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000979}
980
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981// Test that bitrate cannot be set for CBR codecs.
982// Bitrate is ignored if it is higher than the fixed bitrate.
983// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700985 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986
987 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700988 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700989 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200990
991 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700992 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700993 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200994
995 send_parameters_.max_bandwidth_bps = 128;
996 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
minyue7a973442016-10-20 03:27:12 -0700997 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998}
999
skvlade0d46372016-04-07 22:59:22 -07001000// Test that the per-stream bitrate limit and the global
1001// bitrate limit both apply.
1002TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1003 EXPECT_TRUE(SetupSendStream());
1004
1005 // opus, default bitrate == 64000.
1006 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1007 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1008 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1009 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1010
1011 // CBR codecs allow both maximums to exceed the bitrate.
1012 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1013 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1014 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1015 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1016
1017 // CBR codecs don't allow per stream maximums to be too low.
1018 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1019 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1020}
1021
1022// Test that an attempt to set RtpParameters for a stream that does not exist
1023// fails.
1024TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1025 EXPECT_TRUE(SetupChannel());
1026 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001027 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001028 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1029
1030 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001031 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001032}
1033
1034TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001035 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001036 // This test verifies that setting RtpParameters succeeds only if
1037 // the structure contains exactly one encoding.
1038 // TODO(skvlad): Update this test when we start supporting setting parameters
1039 // for each encoding individually.
1040
1041 EXPECT_TRUE(SetupSendStream());
deadbeeffb2aced2017-01-06 23:05:37 -08001042 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001043 // Two or more encodings should result in failure.
1044 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001045 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001046 // Zero encodings should also fail.
1047 parameters.encodings.clear();
1048 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
1049}
1050
1051// Changing the SSRC through RtpParameters is not allowed.
1052TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1053 EXPECT_TRUE(SetupSendStream());
1054 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
1055 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
1056 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -07001057}
1058
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001059// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001060// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001061TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1062 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001063 SetSend(true);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001064 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1065 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001066 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001067 ASSERT_EQ(1u, parameters.encodings.size());
1068 ASSERT_TRUE(parameters.encodings[0].active);
1069 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001070 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001071 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
1072
1073 // Now change it back to active and verify we resume sending.
1074 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001076 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1077}
1078
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001079// Test that SetRtpSendParameters configures the correct encoding channel for
1080// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001081TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1082 SetupForMultiSendStream();
1083 // Create send streams.
1084 for (uint32_t ssrc : kSsrcs4) {
1085 EXPECT_TRUE(
1086 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1087 }
1088 // Configure one stream to be limited by the stream config, another to be
1089 // limited by the global max, and the third one with no per-stream limit
1090 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001091 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001092 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1093 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1094 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1095
1096 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1097 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1098 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1099
1100 // Remove the global cap; the streams should switch to their respective
1101 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001102 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001103 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1104 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1105 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1106}
1107
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001108// Test that GetRtpSendParameters returns the currently configured codecs.
1109TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001110 EXPECT_TRUE(SetupSendStream());
1111 cricket::AudioSendParameters parameters;
1112 parameters.codecs.push_back(kIsacCodec);
1113 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001114 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001115
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001116 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001117 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001118 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1119 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001120}
1121
deadbeefcb443432016-12-12 11:12:36 -08001122// Test that GetRtpSendParameters returns an SSRC.
1123TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1124 EXPECT_TRUE(SetupSendStream());
1125 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
1126 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1127 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1128}
1129
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001130// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001131TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132 EXPECT_TRUE(SetupSendStream());
1133 cricket::AudioSendParameters parameters;
1134 parameters.codecs.push_back(kIsacCodec);
1135 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001136 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001138 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001139
1140 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001141 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001143 // ... And this shouldn't change the params returned by GetRtpSendParameters.
1144 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrc1);
1145 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrc1));
1146}
1147
1148// Test that GetRtpReceiveParameters returns the currently configured codecs.
1149TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1150 EXPECT_TRUE(SetupRecvStream());
1151 cricket::AudioRecvParameters parameters;
1152 parameters.codecs.push_back(kIsacCodec);
1153 parameters.codecs.push_back(kPcmuCodec);
1154 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1155
1156 webrtc::RtpParameters rtp_parameters =
1157 channel_->GetRtpReceiveParameters(kSsrc1);
1158 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1159 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1160 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1161}
1162
deadbeefcb443432016-12-12 11:12:36 -08001163// Test that GetRtpReceiveParameters returns an SSRC.
1164TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1165 EXPECT_TRUE(SetupRecvStream());
1166 webrtc::RtpParameters rtp_parameters =
1167 channel_->GetRtpReceiveParameters(kSsrc1);
1168 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1169 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1170}
1171
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001172// Test that if we set/get parameters multiple times, we get the same results.
1173TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1174 EXPECT_TRUE(SetupRecvStream());
1175 cricket::AudioRecvParameters parameters;
1176 parameters.codecs.push_back(kIsacCodec);
1177 parameters.codecs.push_back(kPcmuCodec);
1178 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1179
1180 webrtc::RtpParameters initial_params =
1181 channel_->GetRtpReceiveParameters(kSsrc1);
1182
1183 // We should be able to set the params we just got.
1184 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrc1, initial_params));
1185
1186 // ... And this shouldn't change the params returned by
1187 // GetRtpReceiveParameters.
1188 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrc1);
1189 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrc1));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001190}
1191
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192// Test that we apply codecs properly.
1193TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001194 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001195 cricket::AudioSendParameters parameters;
1196 parameters.codecs.push_back(kIsacCodec);
1197 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001198 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001199 parameters.codecs[0].id = 96;
1200 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001201 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001202 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001203 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
1204 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1205 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1206 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1207 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1208 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1209 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1210 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001211 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001212}
1213
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001214// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1215// to apply.
1216TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001217 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001218 cricket::AudioSendParameters parameters;
1219 parameters.codecs.push_back(kIsacCodec);
1220 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001221 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001222 parameters.codecs[0].id = 96;
1223 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001224 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001225 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001226 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001227 // Calling SetSendCodec again with same codec which is already set.
1228 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001229 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001230 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001231}
1232
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001233// Verify that G722 is set with 16000 samples per second to WebRTC.
1234TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001235 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001236 cricket::AudioSendParameters parameters;
1237 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001238 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001239 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001240 EXPECT_STREQ("G722", gcodec.plname);
1241 EXPECT_EQ(1, gcodec.channels);
1242 EXPECT_EQ(16000, gcodec.plfreq);
1243}
1244
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001245// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001246TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001247 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001248 cricket::AudioSendParameters parameters;
1249 parameters.codecs.push_back(kOpusCodec);
1250 parameters.codecs[0].bitrate = 0;
1251 parameters.codecs[0].clockrate = 50000;
1252 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001253}
1254
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001255// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001256TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001257 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kOpusCodec);
1260 parameters.codecs[0].bitrate = 0;
1261 parameters.codecs[0].channels = 0;
1262 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001263}
1264
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001265// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001267 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001268 cricket::AudioSendParameters parameters;
1269 parameters.codecs.push_back(kOpusCodec);
1270 parameters.codecs[0].bitrate = 0;
1271 parameters.codecs[0].channels = 0;
1272 parameters.codecs[0].params["stereo"] = "1";
1273 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001274}
1275
1276// Test that if channel is 1 for opus and there's no stereo, we fail.
1277TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001278 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001279 cricket::AudioSendParameters parameters;
1280 parameters.codecs.push_back(kOpusCodec);
1281 parameters.codecs[0].bitrate = 0;
1282 parameters.codecs[0].channels = 1;
1283 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
1286// Test that if channel is 1 for opus and stereo=0, we fail.
1287TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001288 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 cricket::AudioSendParameters parameters;
1290 parameters.codecs.push_back(kOpusCodec);
1291 parameters.codecs[0].bitrate = 0;
1292 parameters.codecs[0].channels = 1;
1293 parameters.codecs[0].params["stereo"] = "0";
1294 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295}
1296
1297// Test that if channel is 1 for opus and stereo=1, we fail.
1298TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001299 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001300 cricket::AudioSendParameters parameters;
1301 parameters.codecs.push_back(kOpusCodec);
1302 parameters.codecs[0].bitrate = 0;
1303 parameters.codecs[0].channels = 1;
1304 parameters.codecs[0].params["stereo"] = "1";
1305 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001306}
1307
1308// Test that with bitrate=0 and no stereo,
1309// channels and bitrate are 1 and 32000.
1310TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001311 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001312 cricket::AudioSendParameters parameters;
1313 parameters.codecs.push_back(kOpusCodec);
1314 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001315 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001316 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001317}
1318
1319// Test that with bitrate=0 and stereo=0,
1320// channels and bitrate are 1 and 32000.
1321TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001322 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001323 cricket::AudioSendParameters parameters;
1324 parameters.codecs.push_back(kOpusCodec);
1325 parameters.codecs[0].bitrate = 0;
1326 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001327 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001328 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329}
1330
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001331// Test that with bitrate=invalid and stereo=0,
1332// channels and bitrate are 1 and 32000.
1333TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001334 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001335 cricket::AudioSendParameters parameters;
1336 parameters.codecs.push_back(kOpusCodec);
1337 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001338 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001340 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001341 CheckSendCodec(kSsrc1, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001342
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001343 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001344 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001345 CheckSendCodec(kSsrc1, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001346}
1347
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348// Test that with bitrate=0 and stereo=1,
1349// channels and bitrate are 2 and 64000.
1350TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001351 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001352 cricket::AudioSendParameters parameters;
1353 parameters.codecs.push_back(kOpusCodec);
1354 parameters.codecs[0].bitrate = 0;
1355 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001356 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001357 CheckSendCodec(kSsrc1, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358}
1359
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001360// Test that with bitrate=invalid and stereo=1,
1361// channels and bitrate are 2 and 64000.
1362TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001363 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001364 cricket::AudioSendParameters parameters;
1365 parameters.codecs.push_back(kOpusCodec);
1366 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001367 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001368 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001369 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001370 CheckSendCodec(kSsrc1, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001371
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001373 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001374 CheckSendCodec(kSsrc1, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001375}
1376
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377// Test that with bitrate=N and stereo unset,
1378// channels and bitrate are 1 and N.
1379TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001380 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001381 cricket::AudioSendParameters parameters;
1382 parameters.codecs.push_back(kOpusCodec);
1383 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001384 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001385 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386 EXPECT_EQ(111, gcodec.pltype);
1387 EXPECT_EQ(96000, gcodec.rate);
1388 EXPECT_STREQ("opus", gcodec.plname);
1389 EXPECT_EQ(1, gcodec.channels);
1390 EXPECT_EQ(48000, gcodec.plfreq);
1391}
1392
1393// Test that with bitrate=N and stereo=0,
1394// channels and bitrate are 1 and N.
1395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].bitrate = 30000;
1400 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001401 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001402 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403}
1404
1405// Test that with bitrate=N and without any parameters,
1406// channels and bitrate are 1 and N.
1407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001408 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 cricket::AudioSendParameters parameters;
1410 parameters.codecs.push_back(kOpusCodec);
1411 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001412 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001413 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414}
1415
1416// Test that with bitrate=N and stereo=1,
1417// channels and bitrate are 2 and N.
1418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 30000;
1423 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001424 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001425 CheckSendCodec(kSsrc1, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001428// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1429// Also test that the "maxaveragebitrate" can't be set to values outside the
1430// range of 6000 and 510000
1431TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001432 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001433 cricket::AudioSendParameters parameters;
1434 parameters.codecs.push_back(kOpusCodec);
1435 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001436 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001439 EXPECT_EQ(6000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001440
1441 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001444 EXPECT_EQ(510000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001445
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001447 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001448 EXPECT_EQ(200000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001449}
1450
stefan13f1a0a2016-11-30 07:22:58 -08001451TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1452 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1453 200000);
1454}
1455
1456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1457 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1458}
1459
1460TEST_F(WebRtcVoiceEngineTestFake,
1461 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1462 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1463}
1464
1465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1466 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1467}
1468
1469TEST_F(WebRtcVoiceEngineTestFake,
1470 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1471 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1472 200000);
1473 send_parameters_.max_bandwidth_bps = 300000;
1474 SetSendParameters(send_parameters_);
1475 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1476 << "Setting max bitrate should keep previous min bitrate.";
1477 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1478 << "Setting max bitrate should not reset start bitrate.";
1479 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1480}
1481
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001482// Test that we can enable NACK with opus as caller.
1483TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001484 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 cricket::AudioSendParameters parameters;
1486 parameters.codecs.push_back(kOpusCodec);
1487 parameters.codecs[0].AddFeedbackParam(
1488 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1489 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001490 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001491 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001492 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001495// Test that we can enable NACK with opus as callee.
1496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001497 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 cricket::AudioSendParameters parameters;
1499 parameters.codecs.push_back(kOpusCodec);
1500 parameters.codecs[0].AddFeedbackParam(
1501 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1502 cricket::kParamValueEmpty));
solenberg8189b022016-06-14 12:13:00 -07001503 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001504 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001505 // NACK should be enabled even with no send stream.
solenberg8189b022016-06-14 12:13:00 -07001506 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001507
1508 EXPECT_TRUE(channel_->AddSendStream(
1509 cricket::StreamParams::CreateLegacy(kSsrc1)));
solenberg971cab02016-06-14 10:02:41 -07001510 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001511}
1512
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513// Test that we can enable NACK on receive streams.
1514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001515 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001516 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001517 cricket::AudioSendParameters parameters;
1518 parameters.codecs.push_back(kOpusCodec);
1519 parameters.codecs[0].AddFeedbackParam(
1520 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1521 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001522 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001523 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001525 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001526 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
1529// Test that we can disable NACK.
1530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 cricket::AudioSendParameters parameters;
1533 parameters.codecs.push_back(kOpusCodec);
1534 parameters.codecs[0].AddFeedbackParam(
1535 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1536 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001537 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001538 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 parameters.codecs.clear();
1541 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001543 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001544}
1545
1546// Test that we can disable NACK on receive streams.
1547TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001548 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001549 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
1552 parameters.codecs[0].AddFeedbackParam(
1553 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1554 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001555 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001556 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001557 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001558
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001559 parameters.codecs.clear();
1560 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001561 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001562 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001563 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
1566// Test that NACK is enabled on a new receive stream.
1567TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kIsacCodec);
1571 parameters.codecs.push_back(kCn16000Codec);
1572 parameters.codecs[0].AddFeedbackParam(
1573 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1574 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001575 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001576 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577
solenberg8189b022016-06-14 12:13:00 -07001578 EXPECT_TRUE(AddRecvStream(kSsrc2));
1579 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
1580 EXPECT_TRUE(AddRecvStream(kSsrc3));
1581 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc3).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001582}
1583
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001584// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001585TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001586 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001587 cricket::AudioSendParameters parameters;
1588 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001590 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001591}
1592
1593// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001595 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 cricket::AudioSendParameters parameters;
1597 parameters.codecs.push_back(kOpusCodec);
1598 parameters.codecs[0].bitrate = 0;
1599 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001600 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001601 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001602}
1603
1604// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001605TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001606 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 cricket::AudioSendParameters parameters;
1608 parameters.codecs.push_back(kOpusCodec);
1609 parameters.codecs[0].bitrate = 0;
1610 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001611 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001612 EXPECT_TRUE(GetCodecFec(kSsrc1));
1613 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001614}
1615
1616// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kOpusCodec);
1621 parameters.codecs[0].bitrate = 0;
1622 parameters.codecs[0].params["stereo"] = "1";
1623 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001625 EXPECT_TRUE(GetCodecFec(kSsrc1));
1626 CheckSendCodec(kSsrc1, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001627}
1628
1629// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001630TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001631 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001632 cricket::AudioSendParameters parameters;
1633 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001635 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001636}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001637
1638// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1639TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001640 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001641 cricket::AudioSendParameters parameters;
1642 parameters.codecs.push_back(kIsacCodec);
1643 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001644 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001645 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001646}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001647
1648// Test that Opus FEC status can be changed.
1649TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001650 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001651 cricket::AudioSendParameters parameters;
1652 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001654 EXPECT_FALSE(GetCodecFec(kSsrc1));
1655
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001656 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001658 EXPECT_TRUE(GetCodecFec(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001659}
1660
stefanba4c0e42016-02-04 04:12:24 -08001661TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001662 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001663 cricket::AudioSendParameters send_parameters;
1664 send_parameters.codecs.push_back(kOpusCodec);
1665 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001666 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001667
1668 cricket::AudioRecvParameters recv_parameters;
1669 recv_parameters.codecs.push_back(kIsacCodec);
1670 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg8189b022016-06-14 12:13:00 -07001671 EXPECT_TRUE(AddRecvStream(kSsrc1));
stefanba4c0e42016-02-04 04:12:24 -08001672 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1673 EXPECT_FALSE(
1674 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1675
ossudedfd282016-06-14 07:12:39 -07001676 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001678 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1679 EXPECT_TRUE(
1680 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1681}
1682
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001683// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1684TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001685 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001686 cricket::AudioSendParameters parameters;
1687 parameters.codecs.push_back(kOpusCodec);
1688 parameters.codecs[0].bitrate = 0;
1689 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));
1692 EXPECT_EQ(12000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001693
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001695 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001696 EXPECT_EQ(24000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001697}
1698
1699// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1700TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001701 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 cricket::AudioSendParameters parameters;
1703 parameters.codecs.push_back(kOpusCodec);
1704 parameters.codecs[0].bitrate = 0;
1705 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001706 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001707 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrc1));
1708 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001709
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001712 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001713}
1714
1715// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1716TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001717 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 cricket::AudioSendParameters parameters;
1719 parameters.codecs.push_back(kOpusCodec);
1720 parameters.codecs[0].bitrate = 0;
1721 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001723 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrc1));
1724 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001725
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001726 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001728 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001729}
1730
1731// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1732TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001733 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 cricket::AudioSendParameters parameters;
1735 parameters.codecs.push_back(kOpusCodec);
1736 parameters.codecs[0].bitrate = 0;
1737 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001739 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrc1));
1740 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001741
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001744 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001745}
1746
1747// Test 24000 < maxplaybackrate triggers Opus full band mode.
1748TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001749 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001750 cricket::AudioSendParameters parameters;
1751 parameters.codecs.push_back(kOpusCodec);
1752 parameters.codecs[0].bitrate = 0;
1753 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001754 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001755 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrc1));
1756 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001757
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001760 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001761}
1762
1763// Test Opus that without maxplaybackrate, default playback rate is used.
1764TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001765 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 cricket::AudioSendParameters parameters;
1767 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001768 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001769 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001770}
1771
1772// Test the with non-Opus, maxplaybackrate has no effect.
1773TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001774 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 cricket::AudioSendParameters parameters;
1776 parameters.codecs.push_back(kIsacCodec);
1777 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001778 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001779 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001780}
1781
1782// Test maxplaybackrate can be set on two streams.
1783TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001784 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001785 cricket::AudioSendParameters parameters;
1786 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001788 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001789
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001790 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001793
1794 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
minyue7a973442016-10-20 03:27:12 -07001795 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc2));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001796}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001797
Minyue Li7100dcd2015-03-27 05:05:59 +01001798// Test that with usedtx=0, Opus DTX is off.
1799TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001800 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001801 cricket::AudioSendParameters parameters;
1802 parameters.codecs.push_back(kOpusCodec);
1803 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001804 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001805 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001806}
1807
1808// Test that with usedtx=1, Opus DTX is on.
1809TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001810 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 cricket::AudioSendParameters parameters;
1812 parameters.codecs.push_back(kOpusCodec);
1813 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001814 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001815 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001816}
1817
1818// Test that usedtx=1 works with stereo Opus.
1819TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001820 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001821 cricket::AudioSendParameters parameters;
1822 parameters.codecs.push_back(kOpusCodec);
1823 parameters.codecs[0].params["usedtx"] = "1";
1824 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001826 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001827}
1828
1829// Test that usedtx=1 does not work with non Opus.
1830TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
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(kIsacCodec);
1834 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001837}
1838
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001839// Test that we can switch back and forth between Opus and ISAC with CN.
1840TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001841 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001842
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 cricket::AudioSendParameters opus_parameters;
1844 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001845 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001846 {
1847 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1848 EXPECT_EQ(111, gcodec.pltype);
1849 EXPECT_STREQ("opus", gcodec.plname);
1850 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001851
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 cricket::AudioSendParameters isac_parameters;
1853 isac_parameters.codecs.push_back(kIsacCodec);
1854 isac_parameters.codecs.push_back(kCn16000Codec);
1855 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001856 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001857 {
1858 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1859 EXPECT_EQ(103, gcodec.pltype);
1860 EXPECT_STREQ("ISAC", gcodec.plname);
1861 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001862
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001864 {
1865 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1866 EXPECT_EQ(111, gcodec.pltype);
1867 EXPECT_STREQ("opus", gcodec.plname);
1868 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001869}
1870
1871// Test that we handle various ways of specifying bitrate.
1872TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001873 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001874 cricket::AudioSendParameters parameters;
1875 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001877 {
1878 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1879 EXPECT_EQ(103, gcodec.pltype);
1880 EXPECT_STREQ("ISAC", gcodec.plname);
1881 EXPECT_EQ(32000, gcodec.rate);
1882 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001883
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001884 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001885 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001886 {
1887 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1888 EXPECT_EQ(103, gcodec.pltype);
1889 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001890 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001891 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001894 {
1895 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1896 EXPECT_EQ(103, gcodec.pltype);
1897 EXPECT_STREQ("ISAC", gcodec.plname);
1898 EXPECT_EQ(28000, gcodec.rate);
1899 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001902 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001903 {
1904 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1905 EXPECT_EQ(0, gcodec.pltype);
1906 EXPECT_STREQ("PCMU", gcodec.plname);
1907 EXPECT_EQ(64000, gcodec.rate);
1908 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001909
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001910 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001912 {
1913 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1914 EXPECT_EQ(0, gcodec.pltype);
1915 EXPECT_STREQ("PCMU", gcodec.plname);
1916 EXPECT_EQ(64000, gcodec.rate);
1917 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001918
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001919 parameters.codecs[0] = kOpusCodec;
1920 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001921 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001922 {
1923 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1924 EXPECT_EQ(111, gcodec.pltype);
1925 EXPECT_STREQ("opus", gcodec.plname);
1926 EXPECT_EQ(32000, gcodec.rate);
1927 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928}
1929
Brave Yao5225dd82015-03-26 07:39:19 +08001930// Test that we could set packet size specified in kCodecParamPTime.
1931TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001932 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001933 cricket::AudioSendParameters parameters;
1934 parameters.codecs.push_back(kOpusCodec);
1935 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001936 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001937 EXPECT_EQ(1920, GetCodecPacSize(kSsrc1)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001938
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001939 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001940 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001941 EXPECT_EQ(480, GetCodecPacSize(kSsrc1)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001942
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001943 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001944 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001945 EXPECT_EQ(2880, GetCodecPacSize(kSsrc1)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001946
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1948 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001949 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001950 EXPECT_EQ(480, GetCodecPacSize(
1951 kSsrc1)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001952
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1954 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001955 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001956 EXPECT_EQ(640, GetCodecPacSize(
1957 kSsrc1)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001958}
1959
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001960// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001961TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001962 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001963 cricket::AudioSendParameters parameters;
1964 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001965}
1966
1967// Test that we can set send codecs even with telephone-event codec as the first
1968// one on the list.
1969TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001971 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001972 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001973 parameters.codecs.push_back(kIsacCodec);
1974 parameters.codecs.push_back(kPcmuCodec);
1975 parameters.codecs[0].id = 98; // DTMF
1976 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001978 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001979 EXPECT_EQ(96, gcodec.pltype);
1980 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001981 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001982}
1983
solenberg31642aa2016-03-14 08:00:37 -07001984// Test that payload type range is limited for telephone-event codec.
1985TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001986 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001987 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001988 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001989 parameters.codecs.push_back(kIsacCodec);
1990 parameters.codecs[0].id = 0; // DTMF
1991 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001993 EXPECT_TRUE(channel_->CanInsertDtmf());
1994 parameters.codecs[0].id = 128; // DTMF
1995 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1996 EXPECT_FALSE(channel_->CanInsertDtmf());
1997 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001999 EXPECT_TRUE(channel_->CanInsertDtmf());
2000 parameters.codecs[0].id = -1; // DTMF
2001 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2002 EXPECT_FALSE(channel_->CanInsertDtmf());
2003}
2004
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002005// Test that we can set send codecs even with CN codec as the first
2006// one on the list.
2007TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
2010 parameters.codecs.push_back(kCn16000Codec);
2011 parameters.codecs.push_back(kIsacCodec);
2012 parameters.codecs.push_back(kPcmuCodec);
2013 parameters.codecs[0].id = 98; // wideband CN
2014 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002015 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002016 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2017 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2018 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2019 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2020 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002021}
2022
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002023// Test that we set VAD and DTMF types correctly as caller.
2024TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002025 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002026 cricket::AudioSendParameters parameters;
2027 parameters.codecs.push_back(kIsacCodec);
2028 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002029 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002030 parameters.codecs.push_back(kCn16000Codec);
2031 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002032 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002033 parameters.codecs[0].id = 96;
2034 parameters.codecs[2].id = 97; // wideband CN
2035 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002036 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002037 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2038 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2039 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2040 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2041 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2042 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2043 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002044 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002045}
2046
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002047// Test that we set VAD and DTMF types correctly as callee.
2048TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002049 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002050 cricket::AudioSendParameters parameters;
2051 parameters.codecs.push_back(kIsacCodec);
2052 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002053 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002054 parameters.codecs.push_back(kCn16000Codec);
2055 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002056 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002057 parameters.codecs[0].id = 96;
2058 parameters.codecs[2].id = 97; // wideband CN
2059 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002060 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002061 EXPECT_TRUE(channel_->AddSendStream(
2062 cricket::StreamParams::CreateLegacy(kSsrc1)));
2063
minyue7a973442016-10-20 03:27:12 -07002064 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2065 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2066 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2067 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2068 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2069 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2070 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002071 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002072}
2073
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002074// Test that we only apply VAD if we have a CN codec that matches the
2075// send codec clockrate.
2076TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002077 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002078 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002079 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002080 parameters.codecs.push_back(kIsacCodec);
2081 parameters.codecs.push_back(kCn16000Codec);
2082 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002084 {
2085 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2086 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2087 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2088 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2089 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2090 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2091 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002092 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002093 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002094 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002095 {
2096 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2097 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2098 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2099 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002101 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002102 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002103 {
2104 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2105 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2106 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2107 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2108 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2109 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2110 }
Brave Yao5225dd82015-03-26 07:39:19 +08002111 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002112 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002113 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002114 {
2115 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2116 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2117 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2118 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002119}
2120
2121// Test that we perform case-insensitive matching of codec names.
2122TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002123 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002124 cricket::AudioSendParameters parameters;
2125 parameters.codecs.push_back(kIsacCodec);
2126 parameters.codecs.push_back(kPcmuCodec);
2127 parameters.codecs.push_back(kCn16000Codec);
2128 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002129 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002130 parameters.codecs[0].name = "iSaC";
2131 parameters.codecs[0].id = 96;
2132 parameters.codecs[2].id = 97; // wideband CN
2133 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002134 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002135 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2136 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2137 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2138 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2139 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2140 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2141 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002142 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002143}
2144
stefanba4c0e42016-02-04 04:12:24 -08002145class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2146 public:
2147 WebRtcVoiceEngineWithSendSideBweTest()
2148 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2149};
2150
2151TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2152 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002153 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002154 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002155 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2156 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2157 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002158 extension.id);
2159 return;
2160 }
2161 }
2162 FAIL() << "Transport sequence number extension not in header-extension list.";
2163}
2164
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002165// Test support for audio level header extension.
2166TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002167 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002168}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002169TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002170 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002171}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002172
solenbergd4adce42016-11-17 06:26:52 -08002173// Test support for transport sequence number header extension.
2174TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2175 TestSetSendRtpHeaderExtensions(
2176 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002177}
solenbergd4adce42016-11-17 06:26:52 -08002178TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2179 TestSetRecvRtpHeaderExtensions(
2180 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181}
2182
solenberg1ac56142015-10-13 03:58:19 -07002183// Test that we can create a channel and start sending on it.
2184TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002185 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002186 SetSendParameters(send_parameters_);
2187 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002188 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002189 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002190 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2191}
2192
2193// Test that a channel will send if and only if it has a source and is enabled
2194// for sending.
2195TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002196 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002197 SetSendParameters(send_parameters_);
2198 SetAudioSend(kSsrc1, true, nullptr);
2199 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002200 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002201 SetAudioSend(kSsrc1, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002203 SetAudioSend(kSsrc1, true, nullptr);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002204 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002205}
2206
solenberg94218532016-06-16 10:53:22 -07002207// Test that a channel is muted/unmuted.
2208TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2209 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002210 SetSendParameters(send_parameters_);
solenberg94218532016-06-16 10:53:22 -07002211 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002212 SetAudioSend(kSsrc1, true, nullptr);
solenberg94218532016-06-16 10:53:22 -07002213 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002214 SetAudioSend(kSsrc1, false, nullptr);
solenberg94218532016-06-16 10:53:22 -07002215 EXPECT_TRUE(GetSendStream(kSsrc1).muted());
2216}
2217
solenberg6d6e7c52016-04-13 09:07:30 -07002218// Test that SetSendParameters() does not alter a stream's send state.
2219TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2220 EXPECT_TRUE(SetupSendStream());
2221 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2222
2223 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002224 SetSend(true);
solenberg6d6e7c52016-04-13 09:07:30 -07002225 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2226
2227 // Changing RTP header extensions will recreate the AudioSendStream.
2228 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002229 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002230 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002231 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2232
2233 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002234 SetSend(false);
solenberg6d6e7c52016-04-13 09:07:30 -07002235 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2236
2237 // Changing RTP header extensions will recreate the AudioSendStream.
2238 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002239 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002240 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2241}
2242
solenberg1ac56142015-10-13 03:58:19 -07002243// Test that we can create a channel and start playing out on it.
2244TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002245 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002246 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002247 channel_->SetPlayout(true);
2248 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
2249 channel_->SetPlayout(false);
2250 EXPECT_FALSE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002251}
2252
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002253// Test that we can add and remove send streams.
2254TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2255 SetupForMultiSendStream();
2256
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002257 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002258 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002259
solenbergc96df772015-10-21 13:01:53 -07002260 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002261 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002262 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002263 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002264 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002265 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002266 }
tfarina5237aaf2015-11-10 23:44:30 -08002267 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002268
solenbergc96df772015-10-21 13:01:53 -07002269 // Delete the send streams.
2270 for (uint32_t ssrc : kSsrcs4) {
2271 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002272 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002273 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002274 }
solenbergc96df772015-10-21 13:01:53 -07002275 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002276}
2277
2278// Test SetSendCodecs correctly configure the codecs in all send streams.
2279TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2280 SetupForMultiSendStream();
2281
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002283 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002284 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002285 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002286 }
2287
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002288 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002289 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002290 parameters.codecs.push_back(kIsacCodec);
2291 parameters.codecs.push_back(kCn16000Codec);
2292 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002293 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002294
2295 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002296 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002297 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2298 const auto& send_codec_spec =
2299 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2300 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2301 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2302 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2303 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2304 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305 }
2306
minyue7a973442016-10-20 03:27:12 -07002307 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002308 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002309 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002310 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002311 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2312 const auto& send_codec_spec =
2313 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2314 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2315 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2316 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2317 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002318 }
2319}
2320
2321// Test we can SetSend on all send streams correctly.
2322TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2323 SetupForMultiSendStream();
2324
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002325 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002326 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002327 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002328 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002329 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002330 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002331 }
2332
2333 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002334 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002335 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002336 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002337 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002338 }
2339
2340 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002341 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002342 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002343 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002344 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002345 }
2346}
2347
2348// Test we can set the correct statistics on all send streams.
2349TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2350 SetupForMultiSendStream();
2351
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002352 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002353 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002354 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002355 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002356 }
solenberg85a04962015-10-27 03:35:21 -07002357
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002358 // Create a receive stream to check that none of the send streams end up in
2359 // the receive stream stats.
solenberg8189b022016-06-14 12:13:00 -07002360 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg971cab02016-06-14 10:02:41 -07002361
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002362 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002363 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002364 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002365 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002366
solenberg85a04962015-10-27 03:35:21 -07002367 // Check stats for the added streams.
2368 {
2369 cricket::VoiceMediaInfo info;
2370 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002371
solenberg85a04962015-10-27 03:35:21 -07002372 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002373 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002374 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002375 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002376 }
hbos1acfbd22016-11-17 23:43:29 -08002377 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002378
2379 // We have added one receive stream. We should see empty stats.
2380 EXPECT_EQ(info.receivers.size(), 1u);
2381 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 }
solenberg1ac56142015-10-13 03:58:19 -07002383
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002384 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002385 {
2386 cricket::VoiceMediaInfo info;
2387 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2388 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002389 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002390 EXPECT_EQ(0u, info.receivers.size());
2391 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002392
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002393 // Deliver a new packet - a default receive stream should be created and we
2394 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002395 {
2396 cricket::VoiceMediaInfo info;
2397 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2398 SetAudioReceiveStreamStats();
2399 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002400 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002401 EXPECT_EQ(1u, info.receivers.size());
2402 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002403 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002404 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002405}
2406
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002407// Test that we can add and remove receive streams, and do proper send/playout.
2408// We can receive on multiple streams while sending one stream.
2409TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002410 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002411
solenberg1ac56142015-10-13 03:58:19 -07002412 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002413 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002414 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415
solenberg1ac56142015-10-13 03:58:19 -07002416 // Adding another stream should enable playout on the new stream only.
solenberg8189b022016-06-14 12:13:00 -07002417 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002418 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002419 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420
solenberg1ac56142015-10-13 03:58:19 -07002421 // Make sure only the new stream is played out.
aleloi84ef6152016-08-04 05:28:21 -07002422 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423
2424 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg8189b022016-06-14 12:13:00 -07002425 EXPECT_TRUE(AddRecvStream(kSsrc3));
aleloi84ef6152016-08-04 05:28:21 -07002426 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2427 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428
2429 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002430 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002431 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002432
2433 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002434 channel_->SetPlayout(false);
2435 EXPECT_FALSE(GetRecvStream(kSsrc2).started());
2436 EXPECT_FALSE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437
aleloi84ef6152016-08-04 05:28:21 -07002438 // Restart playout and make sure recv streams are played out.
2439 channel_->SetPlayout(true);
2440 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2441 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002442
aleloi84ef6152016-08-04 05:28:21 -07002443 // Now remove the recv streams.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2445 EXPECT_TRUE(channel_->RemoveRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446}
2447
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002449// and start sending on it.
2450TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002451 EXPECT_TRUE(SetupSendStream());
solenberg246b8172015-12-08 09:50:23 -08002452 cricket::AudioOptions options_adjust_agc;
2453 options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 webrtc::AgcConfig agc_config;
2455 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2456 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002457 send_parameters_.options = options_adjust_agc;
solenberg059fb442016-10-26 05:12:24 -07002458 SetSendParameters(send_parameters_);
2459 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002460 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2462 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
solenberg059fb442016-10-26 05:12:24 -07002463 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002464 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466}
2467
wu@webrtc.org97077a32013-10-25 21:18:33 +00002468TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002469 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002470 EXPECT_CALL(adm_,
2471 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
wu@webrtc.org97077a32013-10-25 21:18:33 +00002472 webrtc::AgcConfig agc_config;
2473 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2474 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002475 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2476 send_parameters_.options.tx_agc_digital_compression_gain =
2477 rtc::Optional<uint16_t>(9);
2478 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2479 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002480 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002481 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2482 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2483 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2484 EXPECT_TRUE(agc_config.limiterEnable);
2485
2486 // Check interaction with adjust_agc_delta. Both should be respected, for
2487 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002488 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg059fb442016-10-26 05:12:24 -07002489 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002490 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2491 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2492}
2493
wu@webrtc.org97077a32013-10-25 21:18:33 +00002494TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002495 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002496 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2497 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002498 send_parameters_.options.recording_sample_rate =
2499 rtc::Optional<uint32_t>(48000);
2500 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002501 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002502}
2503
minyue6b825df2016-10-31 04:08:32 -07002504TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2505 EXPECT_TRUE(SetupSendStream());
2506 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2507 send_parameters_.options.audio_network_adaptor_config =
2508 rtc::Optional<std::string>("1234");
2509 SetSendParameters(send_parameters_);
2510 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2511 GetAudioNetworkAdaptorConfig(kSsrc1));
2512}
2513
2514TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2515 EXPECT_TRUE(SetupSendStream());
2516 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2517 send_parameters_.options.audio_network_adaptor_config =
2518 rtc::Optional<std::string>("1234");
2519 SetSendParameters(send_parameters_);
2520 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2521 GetAudioNetworkAdaptorConfig(kSsrc1));
2522 const int initial_num = call_.GetNumCreatedSendStreams();
2523 cricket::AudioOptions options;
2524 options.audio_network_adaptor = rtc::Optional<bool>(false);
2525 SetAudioSend(kSsrc1, true, nullptr, &options);
2526 // AudioSendStream expected to be recreated.
2527 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
2528 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrc1));
2529}
2530
2531TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2532 EXPECT_TRUE(SetupSendStream());
2533 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2534 send_parameters_.options.audio_network_adaptor_config =
2535 rtc::Optional<std::string>("1234");
2536 SetSendParameters(send_parameters_);
2537 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2538 GetAudioNetworkAdaptorConfig(kSsrc1));
2539 const int initial_num = call_.GetNumCreatedSendStreams();
2540 cricket::AudioOptions options;
2541 options.audio_network_adaptor = rtc::Optional<bool>();
2542 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2543 // adaptor.
2544 SetAudioSend(kSsrc1, true, nullptr, &options);
2545 // AudioSendStream not expected to be recreated.
2546 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2547 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2548 GetAudioNetworkAdaptorConfig(kSsrc1));
2549}
2550
michaelt6672b262017-01-11 10:17:59 -08002551class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2552 : public WebRtcVoiceEngineTestFake {
2553 public:
2554 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2555 : WebRtcVoiceEngineTestFake(
2556 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2557 "Enabled/") {}
2558};
2559
2560TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2561 EXPECT_TRUE(SetupSendStream());
2562 cricket::AudioSendParameters parameters;
2563 parameters.codecs.push_back(kOpusCodec);
2564 SetSendParameters(parameters);
2565 const int initial_num = call_.GetNumCreatedSendStreams();
2566 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2567
2568 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2569 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
2570 constexpr int kMinOverheadBps = kOverheadPerPacket * 8 * 1000 / 60;
2571 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2572
2573 constexpr int kOpusMinBitrateBps = 6000;
2574 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
2575 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2576 constexpr int kOpusBitrateFbBps = 32000;
2577 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
2578 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2579
2580 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2581 parameters.options.audio_network_adaptor_config =
2582 rtc::Optional<std::string>("1234");
2583 SetSendParameters(parameters);
2584
2585 constexpr int kMinOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 60;
2586 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2587
2588 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
2589 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2590
2591 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
2592 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2593}
2594
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002595// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002596// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002597TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002598 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002599 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002600}
2601
2602TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2603 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002604 EXPECT_TRUE(SetupSendStream());
solenbergff976312016-03-30 23:28:51 -07002605 // SetupSendStream adds a send stream with kSsrc1, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002606 // stream has to use a different SSRC.
solenberg8189b022016-06-14 12:13:00 -07002607 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002608 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002609 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002610 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002611
solenberg85a04962015-10-27 03:35:21 -07002612 // Check stats for the added streams.
2613 {
2614 cricket::VoiceMediaInfo info;
2615 EXPECT_EQ(true, channel_->GetStats(&info));
2616
2617 // We have added one send stream. We should see the stats we've set.
2618 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002619 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002620 // We have added one receive stream. We should see empty stats.
2621 EXPECT_EQ(info.receivers.size(), 1u);
2622 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2623 }
solenberg1ac56142015-10-13 03:58:19 -07002624
solenberg566ef242015-11-06 15:34:49 -08002625 // Start sending - this affects some reported stats.
2626 {
2627 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002628 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002629 EXPECT_EQ(true, channel_->GetStats(&info));
2630 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002631 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002632 }
2633
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002634 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002635 {
2636 cricket::VoiceMediaInfo info;
2637 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2638 EXPECT_EQ(true, channel_->GetStats(&info));
2639 EXPECT_EQ(1u, info.senders.size());
2640 EXPECT_EQ(0u, info.receivers.size());
2641 }
solenberg1ac56142015-10-13 03:58:19 -07002642
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002643 // Deliver a new packet - a default receive stream should be created and we
2644 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002645 {
2646 cricket::VoiceMediaInfo info;
2647 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2648 SetAudioReceiveStreamStats();
2649 EXPECT_EQ(true, channel_->GetStats(&info));
2650 EXPECT_EQ(1u, info.senders.size());
2651 EXPECT_EQ(1u, info.receivers.size());
2652 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002653 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002654 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655}
2656
2657// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002658// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002659TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002660 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002661 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg8189b022016-06-14 12:13:00 -07002662 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -08002663 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664}
2665
2666// Test that the local SSRC is the same on sending and receiving channels if the
2667// receive channel is created before the send channel.
2668TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002669 EXPECT_TRUE(SetupChannel());
solenberg4a0f7b52016-06-16 13:07:33 -07002670 EXPECT_TRUE(AddRecvStream(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002671 EXPECT_TRUE(channel_->AddSendStream(
solenberg4a0f7b52016-06-16 13:07:33 -07002672 cricket::StreamParams::CreateLegacy(kSsrc1)));
2673 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2674 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002675}
2676
2677// Test that we can properly receive packets.
2678TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002679 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002680 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002681 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002682
2683 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2684 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685}
2686
2687// Test that we can properly receive packets on multiple streams.
2688TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002689 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002690 const uint32_t ssrc1 = 1;
2691 const uint32_t ssrc2 = 2;
2692 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002693 EXPECT_TRUE(AddRecvStream(ssrc1));
2694 EXPECT_TRUE(AddRecvStream(ssrc2));
2695 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002696 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002697 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002698 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002700 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002701 }
mflodman3d7db262016-04-29 00:57:13 -07002702
2703 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2704 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2705 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2706
2707 EXPECT_EQ(s1.received_packets(), 0);
2708 EXPECT_EQ(s2.received_packets(), 0);
2709 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002710
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002711 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002712 EXPECT_EQ(s1.received_packets(), 0);
2713 EXPECT_EQ(s2.received_packets(), 0);
2714 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002715
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002717 EXPECT_EQ(s1.received_packets(), 1);
2718 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2719 EXPECT_EQ(s2.received_packets(), 0);
2720 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002721
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002722 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002723 EXPECT_EQ(s1.received_packets(), 1);
2724 EXPECT_EQ(s2.received_packets(), 1);
2725 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2726 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002727
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002728 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002729 EXPECT_EQ(s1.received_packets(), 1);
2730 EXPECT_EQ(s2.received_packets(), 1);
2731 EXPECT_EQ(s3.received_packets(), 1);
2732 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002733
mflodman3d7db262016-04-29 00:57:13 -07002734 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2735 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2736 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737}
2738
solenberg7e63ef02015-11-20 00:19:43 -08002739// Test that receiving on an unsignalled stream works (default channel will be
2740// created).
2741TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
solenbergff976312016-03-30 23:28:51 -07002742 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002743 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2744
solenberg7e63ef02015-11-20 00:19:43 -08002745 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002746
2747 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2748 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2749 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002750}
2751
2752// Test that receiving on an unsignalled stream works (default channel will be
2753// created), and that packets will be forwarded to the default channel
2754// regardless of their SSRCs.
2755TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
solenbergff976312016-03-30 23:28:51 -07002756 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002757 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002758 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2759
mflodman3d7db262016-04-29 00:57:13 -07002760 // Note that ssrc = 0 is not supported.
2761 uint32_t ssrc = 1;
2762 for (; ssrc < 10; ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002763 rtc::SetBE32(&packet[8], ssrc);
2764 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002765
2766 // Verify we only have one default stream.
2767 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2768 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2769 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002770 }
mflodman3d7db262016-04-29 00:57:13 -07002771
2772 // Sending the same ssrc again should not create a new stream.
2773 --ssrc;
2774 DeliverPacket(packet, sizeof(packet));
2775 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2776 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2777 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002778}
2779
2780// Test that a default channel is created even after a signalled stream has been
2781// added, and that this stream will get any packets for unknown SSRCs.
2782TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
solenbergff976312016-03-30 23:28:51 -07002783 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002784 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002785 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2786
2787 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002788 const uint32_t signaled_ssrc = 1;
2789 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002790 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002791 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002792 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2793 packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002794
2795 // Note that the first unknown SSRC cannot be 0, because we only support
2796 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002797 const uint32_t unsignaled_ssrc = 7011;
2798 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002799 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002800 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2801 packet, sizeof(packet)));
2802 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2803
2804 DeliverPacket(packet, sizeof(packet));
2805 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2806
2807 rtc::SetBE32(&packet[8], signaled_ssrc);
2808 DeliverPacket(packet, sizeof(packet));
2809 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2810 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002811}
2812
solenberg0a617e22015-10-20 15:49:38 -07002813// Test that we properly handle failures to add a receive stream.
2814TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002815 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002817 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818}
2819
solenberg0a617e22015-10-20 15:49:38 -07002820// Test that we properly handle failures to add a send stream.
2821TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002822 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002823 voe_.set_fail_create_channel(true);
2824 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2825}
2826
solenberg1ac56142015-10-13 03:58:19 -07002827// Test that AddRecvStream creates new stream.
2828TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002829 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002831 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002832 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002833}
2834
2835// Test that after adding a recv stream, we do not decode more codecs than
2836// those previously passed into SetRecvCodecs.
2837TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002839 cricket::AudioRecvParameters parameters;
2840 parameters.codecs.push_back(kIsacCodec);
2841 parameters.codecs.push_back(kPcmuCodec);
2842 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002843 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002844 int channel_num2 = voe_.GetLastChannel();
2845 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002846 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002847 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848 gcodec.channels = 2;
2849 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2850}
2851
2852// Test that we properly clean up any streams that were added, even if
2853// not explicitly removed.
2854TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002855 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002856 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002857 EXPECT_TRUE(AddRecvStream(1));
2858 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2860 delete channel_;
2861 channel_ = NULL;
2862 EXPECT_EQ(0, voe_.GetNumChannels());
2863}
2864
wu@webrtc.org78187522013-10-07 23:32:02 +00002865TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002866 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002867 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002868}
2869
2870TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002871 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002872 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002873 // Manually delete channel to simulate a failure.
2874 int channel = voe_.GetLastChannel();
2875 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2876 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002877 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002878 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002879 EXPECT_NE(channel, new_channel);
2880 // The last created channel is deleted too.
2881 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002882}
2883
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002884// Test the InsertDtmf on default send stream as caller.
2885TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002886 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002887}
2888
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002889// Test the InsertDtmf on default send stream as callee
2890TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002891 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002892}
2893
2894// Test the InsertDtmf on specified send stream as caller.
2895TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002896 TestInsertDtmf(kSsrc1, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002897}
2898
2899// Test the InsertDtmf on specified send stream as callee.
2900TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002901 TestInsertDtmf(kSsrc1, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902}
2903
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002904TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002905 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002906 EXPECT_CALL(adm_,
2907 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2908 EXPECT_CALL(adm_,
2909 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2910 EXPECT_CALL(adm_,
2911 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912 bool ec_enabled;
2913 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914 webrtc::AecmModes aecm_mode;
2915 bool cng_enabled;
2916 bool agc_enabled;
2917 webrtc::AgcModes agc_mode;
2918 webrtc::AgcConfig agc_config;
2919 bool ns_enabled;
2920 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921 bool stereo_swapping_enabled;
2922 bool typing_detection_enabled;
2923 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924 voe_.GetAecmMode(aecm_mode, cng_enabled);
2925 voe_.GetAgcStatus(agc_enabled, agc_mode);
2926 voe_.GetAgcConfig(agc_config);
2927 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2929 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2930 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002931 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932 EXPECT_FALSE(cng_enabled);
2933 EXPECT_TRUE(agc_enabled);
2934 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2935 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002936 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 EXPECT_FALSE(stereo_swapping_enabled);
2938 EXPECT_TRUE(typing_detection_enabled);
2939 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2940 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002941 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2942 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002943
solenberg246b8172015-12-08 09:50:23 -08002944 // Nothing set in AudioOptions, so everything should be as default.
2945 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002946 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002948 voe_.GetAecmMode(aecm_mode, cng_enabled);
2949 voe_.GetAgcStatus(agc_enabled, agc_mode);
2950 voe_.GetAgcConfig(agc_config);
2951 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2953 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2954 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002955 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956 EXPECT_FALSE(cng_enabled);
2957 EXPECT_TRUE(agc_enabled);
2958 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2959 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002960 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961 EXPECT_FALSE(stereo_swapping_enabled);
2962 EXPECT_TRUE(typing_detection_enabled);
2963 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2964 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002965 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2966 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967
2968 // Turn echo cancellation off
solenberg246b8172015-12-08 09:50:23 -08002969 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002970 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971 voe_.GetEcStatus(ec_enabled, ec_mode);
2972 EXPECT_FALSE(ec_enabled);
2973
2974 // Turn echo cancellation back on, with settings, and make sure
2975 // nothing else changed.
solenberg246b8172015-12-08 09:50:23 -08002976 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002977 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 voe_.GetAecmMode(aecm_mode, cng_enabled);
2980 voe_.GetAgcStatus(agc_enabled, agc_mode);
2981 voe_.GetAgcConfig(agc_config);
2982 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2984 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2985 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002986 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987 EXPECT_TRUE(agc_enabled);
2988 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2989 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002990 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 EXPECT_FALSE(stereo_swapping_enabled);
2992 EXPECT_TRUE(typing_detection_enabled);
2993 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2994 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2995
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002996 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2997 // control.
solenberg246b8172015-12-08 09:50:23 -08002998 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002999 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003000 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003001 voe_.GetAecmMode(aecm_mode, cng_enabled);
3002 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003003 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003004 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3005
3006 // Turn off echo cancellation and delay agnostic aec.
solenberg246b8172015-12-08 09:50:23 -08003007 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3008 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3009 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003010 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003011 voe_.GetEcStatus(ec_enabled, ec_mode);
3012 EXPECT_FALSE(ec_enabled);
3013 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg246b8172015-12-08 09:50:23 -08003014 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003015 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003016 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003017 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003018 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003019 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3020
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021 // Turn off AGC
solenberg246b8172015-12-08 09:50:23 -08003022 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003023 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024 voe_.GetAgcStatus(agc_enabled, agc_mode);
3025 EXPECT_FALSE(agc_enabled);
3026
3027 // Turn AGC back on
solenberg246b8172015-12-08 09:50:23 -08003028 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3029 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003030 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031 voe_.GetAgcStatus(agc_enabled, agc_mode);
3032 EXPECT_TRUE(agc_enabled);
3033 voe_.GetAgcConfig(agc_config);
3034 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3035
3036 // Turn off other options (and stereo swapping on).
solenberg246b8172015-12-08 09:50:23 -08003037 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3038 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3039 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3040 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003041 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003042 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3044 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3045 EXPECT_FALSE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003046 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047 EXPECT_FALSE(typing_detection_enabled);
3048 EXPECT_TRUE(stereo_swapping_enabled);
3049
solenberg1ac56142015-10-13 03:58:19 -07003050 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07003051 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003052 voe_.GetEcStatus(ec_enabled, ec_mode);
3053 voe_.GetNsStatus(ns_enabled, ns_mode);
3054 EXPECT_TRUE(ec_enabled);
3055 EXPECT_EQ(webrtc::kEcConference, ec_mode);
3056 EXPECT_FALSE(ns_enabled);
3057 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
3058}
3059
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003060TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
solenbergff976312016-03-30 23:28:51 -07003061 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062
3063 bool ec_enabled;
3064 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003065 bool agc_enabled;
3066 webrtc::AgcModes agc_mode;
3067 bool ns_enabled;
3068 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069 bool stereo_swapping_enabled;
3070 bool typing_detection_enabled;
3071
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003072 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003073 voe_.GetAgcStatus(agc_enabled, agc_mode);
3074 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3076 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3077 EXPECT_TRUE(ec_enabled);
3078 EXPECT_TRUE(agc_enabled);
3079 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003080 EXPECT_TRUE(IsHighPassFilterEnabled());
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003081 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083}
3084
3085TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3086 webrtc::AgcConfig set_config = {0};
3087 set_config.targetLeveldBOv = 3;
3088 set_config.digitalCompressionGaindB = 9;
3089 set_config.limiterEnable = true;
3090 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003091
3092 webrtc::AgcConfig config = {0};
3093 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3094 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3095 EXPECT_EQ(set_config.digitalCompressionGaindB,
3096 config.digitalCompressionGaindB);
3097 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3098}
3099
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003100TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003101 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003102 EXPECT_CALL(adm_,
3103 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3104 EXPECT_CALL(adm_,
3105 BuiltInAGCIsAvailable()).Times(9).WillRepeatedly(Return(false));
3106 EXPECT_CALL(adm_,
3107 BuiltInNSIsAvailable()).Times(9).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003108 EXPECT_CALL(adm_,
3109 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3110 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3111 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3112 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3113 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003114
kwiberg686a8ef2016-02-26 03:00:35 -08003115 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003116 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003117 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003118 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003119 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003120 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003121
3122 // Have to add a stream to make SetSend work.
3123 cricket::StreamParams stream1;
3124 stream1.ssrcs.push_back(1);
3125 channel1->AddSendStream(stream1);
3126 cricket::StreamParams stream2;
3127 stream2.ssrcs.push_back(2);
3128 channel2->AddSendStream(stream2);
3129
3130 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003131 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003132 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3133 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3134 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003135 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003136 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003137 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003138 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003139
3140 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003141 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003142 parameters_options_no_ns.options.noise_suppression =
3143 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003144 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003145 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003146 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3147 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3148 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003149 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003150
3151 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003152 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003153 parameters_options_no_agc.options.auto_gain_control =
3154 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003155 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003156 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3157 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3158 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003159 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003160
solenberg059fb442016-10-26 05:12:24 -07003161 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003162 bool ec_enabled;
3163 webrtc::EcModes ec_mode;
3164 bool agc_enabled;
3165 webrtc::AgcModes agc_mode;
3166 bool ns_enabled;
3167 webrtc::NsModes ns_mode;
3168 voe_.GetEcStatus(ec_enabled, ec_mode);
3169 voe_.GetAgcStatus(agc_enabled, agc_mode);
3170 voe_.GetNsStatus(ns_enabled, ns_mode);
3171 EXPECT_TRUE(ec_enabled);
3172 EXPECT_TRUE(agc_enabled);
3173 EXPECT_TRUE(ns_enabled);
3174
solenberg059fb442016-10-26 05:12:24 -07003175 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003176 voe_.GetEcStatus(ec_enabled, ec_mode);
3177 voe_.GetAgcStatus(agc_enabled, agc_mode);
3178 voe_.GetNsStatus(ns_enabled, ns_mode);
3179 EXPECT_TRUE(ec_enabled);
3180 EXPECT_TRUE(agc_enabled);
3181 EXPECT_FALSE(ns_enabled);
3182
solenberg059fb442016-10-26 05:12:24 -07003183 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003184 voe_.GetEcStatus(ec_enabled, ec_mode);
3185 voe_.GetAgcStatus(agc_enabled, agc_mode);
3186 voe_.GetNsStatus(ns_enabled, ns_mode);
3187 EXPECT_TRUE(ec_enabled);
3188 EXPECT_FALSE(agc_enabled);
3189 EXPECT_TRUE(ns_enabled);
3190
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003191 // Make sure settings take effect while we are sending.
solenberg059fb442016-10-26 05:12:24 -07003192 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
3193 EXPECT_CALL(apm_, ApplyConfig(testing::_));
3194 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003195 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3196 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003197 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003198 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003199 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003200 rtc::Optional<bool>(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08003201 channel2->SetSend(true);
solenberg059fb442016-10-26 05:12:24 -07003202 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003203 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3204 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3205 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003206 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003207 voe_.GetEcStatus(ec_enabled, ec_mode);
3208 voe_.GetAgcStatus(agc_enabled, agc_mode);
3209 voe_.GetNsStatus(ns_enabled, ns_mode);
3210 EXPECT_TRUE(ec_enabled);
3211 EXPECT_FALSE(agc_enabled);
3212 EXPECT_FALSE(ns_enabled);
3213}
3214
wu@webrtc.orgde305012013-10-31 15:40:38 +00003215// This test verifies DSCP settings are properly applied on voice media channel.
3216TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003217 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003218 cricket::FakeNetworkInterface network_interface;
3219 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003220 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003221
solenberg059fb442016-10-26 05:12:24 -07003222 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3223 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3224
solenbergbc37fc82016-04-04 09:54:44 -07003225 channel.reset(
3226 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003227 channel->SetInterface(&network_interface);
3228 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3229 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3230
3231 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003232 channel.reset(
3233 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003234 channel->SetInterface(&network_interface);
3235 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3236
3237 // Verify that setting the option to false resets the
3238 // DiffServCodePoint.
3239 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003240 channel.reset(
3241 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003242 channel->SetInterface(&network_interface);
3243 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3244 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3245
3246 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003247}
3248
solenberg1ac56142015-10-13 03:58:19 -07003249TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003250 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003251 cricket::WebRtcVoiceMediaChannel* media_channel =
3252 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003253 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003254 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003255 int channel_id = voe_.GetLastChannel();
3256 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3257 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003258 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003259 int channel_id2 = voe_.GetLastChannel();
3260 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003261}
3262
solenberg1ac56142015-10-13 03:58:19 -07003263TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003264 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003265 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003266 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3267 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3268 EXPECT_TRUE(channel_->AddSendStream(
3269 cricket::StreamParams::CreateLegacy(kSsrc1)));
3270 int channel_id = voe_.GetLastChannel();
3271 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3272 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3273 EXPECT_TRUE(channel_->AddSendStream(
3274 cricket::StreamParams::CreateLegacy(kSsrc2)));
3275 int channel_id2 = voe_.GetLastChannel();
3276 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003277}
3278
solenberg4bac9c52015-10-09 02:32:53 -07003279TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003280 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003281 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003282 cricket::StreamParams stream;
3283 stream.ssrcs.push_back(kSsrc2);
3284 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003285 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003286 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003287 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003288}
3289
3290TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003291 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003292 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3293 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003294 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003295 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003296 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3297 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3298 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003299}
3300
pbos8fc7fa72015-07-15 08:02:58 -07003301TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003302 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003303 const std::string kSyncLabel = "AvSyncLabel";
3304
solenbergff976312016-03-30 23:28:51 -07003305 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003306 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3307 sp.sync_label = kSyncLabel;
3308 // Creating two channels to make sure that sync label is set properly for both
3309 // the default voice channel and following ones.
3310 EXPECT_TRUE(channel_->AddRecvStream(sp));
3311 sp.ssrcs[0] += 1;
3312 EXPECT_TRUE(channel_->AddRecvStream(sp));
3313
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003314 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003315 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003316 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003317 << "SyncGroup should be set based on sync_label";
3318 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003319 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003320 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003321}
3322
solenberg3a941542015-11-16 07:34:50 -08003323// TODO(solenberg): Remove, once recv streams are configured through Call.
3324// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003325TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003326 // Test that setting the header extensions results in the expected state
3327 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003328 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003329 ssrcs.push_back(223);
3330 ssrcs.push_back(224);
3331
solenbergff976312016-03-30 23:28:51 -07003332 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003333 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003334 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003335 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003336 cricket::StreamParams::CreateLegacy(ssrc)));
3337 }
3338
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003339 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003340 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003341 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003342 EXPECT_NE(nullptr, s);
3343 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3344 }
3345
3346 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003347 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003348 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003349 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003350 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003351 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003352 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003353 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003354 EXPECT_NE(nullptr, s);
3355 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003356 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3357 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003358 for (const auto& s_ext : s_exts) {
3359 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003360 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003361 }
3362 }
3363 }
3364 }
3365
3366 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003367 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003368 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003369 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003370 EXPECT_NE(nullptr, s);
3371 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3372 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003373}
3374
3375TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3376 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003377 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003378 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003379 static const unsigned char kRtcp[] = {
3380 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3381 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3384 };
jbaucheec21bd2016-03-20 06:15:43 -07003385 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003386
solenbergff976312016-03-30 23:28:51 -07003387 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003388 cricket::WebRtcVoiceMediaChannel* media_channel =
3389 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003390 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003391 EXPECT_TRUE(media_channel->AddRecvStream(
3392 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3393
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003394 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003395 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003396 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003397 EXPECT_EQ(0, s->received_packets());
3398 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3399 EXPECT_EQ(1, s->received_packets());
3400 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3401 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003402}
Minyue2013aec2015-05-13 14:14:42 +02003403
solenberg0a617e22015-10-20 15:49:38 -07003404// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003405// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003406TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003407 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003408 EXPECT_TRUE(AddRecvStream(kSsrc2));
3409 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3410 EXPECT_TRUE(channel_->AddSendStream(
3411 cricket::StreamParams::CreateLegacy(kSsrc3)));
3412 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3413 EXPECT_TRUE(AddRecvStream(kSsrc4));
3414 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003415}
3416
solenberg7602aab2016-11-14 11:30:07 -08003417TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3418 EXPECT_TRUE(SetupRecvStream());
3419 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3420 EXPECT_TRUE(channel_->AddSendStream(
3421 cricket::StreamParams::CreateLegacy(kSsrc2)));
3422 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3423 EXPECT_TRUE(AddRecvStream(kSsrc3));
3424 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3425 EXPECT_TRUE(channel_->AddSendStream(
3426 cricket::StreamParams::CreateLegacy(kSsrc4)));
3427 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3428 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003429}
stefan658910c2015-09-03 05:48:32 -07003430
deadbeef884f5852016-01-15 09:20:04 -08003431TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003432 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003433 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3434 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003435
3436 // Setting the sink before a recv stream exists should do nothing.
3437 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003438 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003439 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3440
3441 // Now try actually setting the sink.
3442 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3443 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3444
3445 // Now try resetting it.
3446 channel_->SetRawAudioSink(kSsrc1, nullptr);
3447 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3448}
3449
3450TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003451 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003452 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3453 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003454
3455 // Should be able to set a default sink even when no stream exists.
3456 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3457
3458 // Create default channel and ensure it's assigned the default sink.
3459 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3460 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3461
3462 // Try resetting the default sink.
3463 channel_->SetRawAudioSink(0, nullptr);
3464 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3465
3466 // Try setting the default sink while the default stream exists.
3467 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3468 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3469
3470 // If we remove and add a default stream, it should get the same sink.
3471 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3472 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3473 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3474}
3475
skvlad7a43d252016-03-22 15:32:27 -07003476// Test that, just like the video channel, the voice channel communicates the
3477// network state to the call.
3478TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003479 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003480
3481 EXPECT_EQ(webrtc::kNetworkUp,
3482 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3483 EXPECT_EQ(webrtc::kNetworkUp,
3484 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3485
3486 channel_->OnReadyToSend(false);
3487 EXPECT_EQ(webrtc::kNetworkDown,
3488 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3489 EXPECT_EQ(webrtc::kNetworkUp,
3490 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3491
3492 channel_->OnReadyToSend(true);
3493 EXPECT_EQ(webrtc::kNetworkUp,
3494 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3495 EXPECT_EQ(webrtc::kNetworkUp,
3496 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3497}
3498
aleloi18e0b672016-10-04 02:45:47 -07003499// Test that playout is still started after changing parameters
3500TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3501 SetupRecvStream();
3502 channel_->SetPlayout(true);
3503 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3504
3505 // Changing RTP header extensions will recreate the AudioReceiveStream.
3506 cricket::AudioRecvParameters parameters;
3507 parameters.extensions.push_back(
3508 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3509 channel_->SetRecvParameters(parameters);
3510
3511 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3512}
3513
stefan658910c2015-09-03 05:48:32 -07003514// Tests that the library initializes and shuts down properly.
3515TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003516 // If the VoiceEngine wants to gather available codecs early, that's fine but
3517 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003518 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003519 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003520 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003521 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003522 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003523 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3524 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003525 EXPECT_TRUE(channel != nullptr);
3526 delete channel;
solenbergff976312016-03-30 23:28:51 -07003527}
stefan658910c2015-09-03 05:48:32 -07003528
solenbergff976312016-03-30 23:28:51 -07003529// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003530TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3531 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3532 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3533 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003534 {
ossuc54071d2016-08-17 02:45:41 -07003535 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003536 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003537 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003538 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003539 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003540 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3541 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3542 EXPECT_TRUE(channel != nullptr);
3543 delete channel;
3544 }
stefan658910c2015-09-03 05:48:32 -07003545}
3546
3547// Tests that the library is configured with the codecs we want.
3548TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003549 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3550 // module.
3551
stefan658910c2015-09-03 05:48:32 -07003552 // Check codecs by name.
solenberg26c8c912015-11-27 04:00:25 -08003553 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003554 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003555 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003556 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003557 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003558 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003559 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003560 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003561 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003562 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003563 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003564 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003565 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003566 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003567 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003568 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003569 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003570 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3571 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3572 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3573 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3574 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3575 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003576 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003577 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003578 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003579 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003580 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003581 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003582 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003583 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003584 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003585 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003586 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003587 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003588 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003589 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003590 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003591 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003592 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003593 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003594 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003595 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003596 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003597 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003598 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003599
stefan658910c2015-09-03 05:48:32 -07003600 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003601 // TODO(ossu): Why are the payload types of codecs with non-static payload
3602 // type assignments checked here? It shouldn't really matter.
3603 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003604 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003605 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3606 if (codec.name == "CN" && codec.clockrate == 16000) {
3607 EXPECT_EQ(105, codec.id);
3608 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3609 EXPECT_EQ(106, codec.id);
3610 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3611 EXPECT_EQ(103, codec.id);
3612 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3613 EXPECT_EQ(104, codec.id);
3614 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3615 EXPECT_EQ(9, codec.id);
3616 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3617 EXPECT_EQ(126, codec.id);
3618 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3619 // Remove these checks once both send and receive side assigns payload types
3620 // dynamically.
3621 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3622 EXPECT_EQ(113, codec.id);
3623 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3624 EXPECT_EQ(112, codec.id);
3625 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3626 EXPECT_EQ(110, codec.id);
3627 } else if (codec.name == "opus") {
3628 EXPECT_EQ(111, codec.id);
3629 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3630 EXPECT_EQ("10", codec.params.find("minptime")->second);
3631 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3632 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003633 }
3634 }
stefan658910c2015-09-03 05:48:32 -07003635}
3636
3637// Tests that VoE supports at least 32 channels
3638TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003639 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003640 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003641 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003642 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003643 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003644
3645 cricket::VoiceMediaChannel* channels[32];
3646 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003647 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003648 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3649 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003650 if (!channel)
3651 break;
stefan658910c2015-09-03 05:48:32 -07003652 channels[num_channels++] = channel;
3653 }
3654
tfarina5237aaf2015-11-10 23:44:30 -08003655 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003656 EXPECT_EQ(expected, num_channels);
3657
3658 while (num_channels > 0) {
3659 delete channels[--num_channels];
3660 }
stefan658910c2015-09-03 05:48:32 -07003661}
3662
3663// Test that we set our preferred codecs properly.
3664TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003665 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3666 // - Check that our builtin codecs are usable by Channel.
3667 // - The codecs provided by the engine is usable by Channel.
3668 // It does not check that the codecs in the RecvParameters are actually
3669 // what we sent in - though it's probably reasonable to expect so, if
3670 // SetRecvParameters returns true.
3671 // I think it will become clear once audio decoder injection is completed.
3672 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003673 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003674 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003675 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003676 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003677 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3678 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003679 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003680 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003681 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003682}
ossu9def8002017-02-09 05:14:32 -08003683
3684TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3685 std::vector<webrtc::AudioCodecSpec> specs;
3686 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3687 spec1.allow_comfort_noise = false;
3688 spec1.supports_network_adaption = true;
3689 specs.push_back(spec1);
3690 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3691 spec2.allow_comfort_noise = false;
3692 specs.push_back(spec2);
3693 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3694 {{"param1", "value1b"},
3695 {"param2", "value2"}}}));
3696 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3697 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3698
3699 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3700 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3701 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3702 .WillOnce(Return(specs));
3703
3704 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3705 auto codecs = engine.recv_codecs();
3706 EXPECT_EQ(11, codecs.size());
3707
3708 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3709 // check the actual values safely, to provide better test results.
3710 auto get_codec =
3711 [&codecs](size_t index) -> const cricket::AudioCodec& {
3712 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3713 if (codecs.size() > index)
3714 return codecs[index];
3715 return missing_codec;
3716 };
3717
3718 // Ensure the general codecs are generated first and in order.
3719 for (size_t i = 0; i != specs.size(); ++i) {
3720 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3721 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3722 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3723 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3724 }
3725
3726 // Find the index of a codec, or -1 if not found, so that we can easily check
3727 // supplementary codecs are orderd after the general codecs.
3728 auto find_codec =
3729 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3730 for (size_t i = 0; i != codecs.size(); ++i) {
3731 const cricket::AudioCodec& codec = codecs[i];
3732 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3733 codec.clockrate == format.clockrate_hz &&
3734 codec.channels == format.num_channels) {
3735 return static_cast<int>(i);
3736 }
3737 }
3738 return -1;
3739 };
3740
3741 // Ensure all supplementary codecs are generated last. Their internal ordering
3742 // is not important.
3743 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3744 const int num_specs = static_cast<int>(specs.size());
3745 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3746 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3747 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3748 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3749 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3750 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3751 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3752}