blob: 612d5c2e6b0fb27eef815b91f8c7272c767877d2 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080014#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000015#include "webrtc/base/byteorder.h"
16#include "webrtc/base/gunit.h"
ossubcd88db2017-02-13 07:04:05 -080017#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080018#include "webrtc/call/call.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/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070028#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070029#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080030#include "webrtc/pc/channel.h"
31#include "webrtc/test/field_trial.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
solenbergbc37fc82016-04-04 09:54:44 -070033using testing::Return;
34using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000035
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020036namespace {
37
deadbeef67cf2c12016-04-13 10:07:16 -070038const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
39const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
40const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
41const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
42const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070043const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
44const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080045const cricket::AudioCodec
46 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
47const cricket::AudioCodec
48 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
49
solenberg85a04962015-10-27 03:35:21 -070050const uint32_t kSsrc1 = 0x99;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080051const uint32_t kSsrc2 = 2;
52const uint32_t kSsrc3 = 3;
solenberg7602aab2016-11-14 11:30:07 -080053const uint32_t kSsrc4 = 0x42;
solenberg85a04962015-10-27 03:35:21 -070054const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055
solenberg971cab02016-06-14 10:02:41 -070056constexpr int kRtpHistoryMs = 5000;
57
henrike@webrtc.org28e20752013-07-10 00:45:36 +000058class FakeVoEWrapper : public cricket::VoEWrapper {
59 public:
60 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
61 : cricket::VoEWrapper(engine, // processing
62 engine, // base
63 engine, // codec
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 engine, // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 engine) { // volume
66 }
67};
skvlad11a9cbf2016-10-07 11:53:05 -070068
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020069} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070
solenbergff976312016-03-30 23:28:51 -070071// Tests that our stub library "works".
72TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070073 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
74 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
75 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070076 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
77 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
78 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -070079 StrictMock<webrtc::test::MockAudioProcessing> apm;
80 EXPECT_CALL(apm, ApplyConfig(testing::_));
81 EXPECT_CALL(apm, SetExtraOptions(testing::_));
82 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
83 cricket::FakeWebRtcVoiceEngine voe(&apm);
solenbergff976312016-03-30 23:28:51 -070084 EXPECT_FALSE(voe.IsInited());
85 {
ossuc54071d2016-08-17 02:45:41 -070086 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -080087 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -070088 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -070089 EXPECT_TRUE(voe.IsInited());
90 }
91 EXPECT_FALSE(voe.IsInited());
92}
93
deadbeef884f5852016-01-15 09:20:04 -080094class FakeAudioSink : public webrtc::AudioSinkInterface {
95 public:
96 void OnData(const Data& audio) override {}
97};
98
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080099class FakeAudioSource : public cricket::AudioSource {
100 void SetSink(Sink* sink) override {}
101};
102
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103class WebRtcVoiceEngineTestFake : public testing::Test {
104 public:
stefanba4c0e42016-02-04 04:12:24 -0800105 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
106
107 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg059fb442016-10-26 05:12:24 -0700108 : call_(webrtc::Call::Config(&event_log_)), voe_(&apm_),
skvlad11a9cbf2016-10-07 11:53:05 -0700109 override_field_trials_(field_trials) {
solenbergbc37fc82016-04-04 09:54:44 -0700110 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
111 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700112 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg059fb442016-10-26 05:12:24 -0700115 EXPECT_CALL(apm_, ApplyConfig(testing::_));
116 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
117 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800118 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
119 // the tests here probe the specific set of codecs provided by the builtin
120 // factory. Those tests should probably be moved elsewhere.
121 engine_.reset(new cricket::WebRtcVoiceEngine(
122 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
123 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200124 send_parameters_.codecs.push_back(kPcmuCodec);
125 recv_parameters_.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 }
solenberg8189b022016-06-14 12:13:00 -0700127
solenbergff976312016-03-30 23:28:51 -0700128 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700129 EXPECT_CALL(apm_, ApplyConfig(testing::_));
130 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700131 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
132 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200133 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000134 }
solenberg8189b022016-06-14 12:13:00 -0700135
solenbergff976312016-03-30 23:28:51 -0700136 bool SetupRecvStream() {
137 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700138 return false;
139 }
solenberg8189b022016-06-14 12:13:00 -0700140 return AddRecvStream(kSsrc1);
solenberg1ac56142015-10-13 03:58:19 -0700141 }
solenberg8189b022016-06-14 12:13:00 -0700142
solenbergff976312016-03-30 23:28:51 -0700143 bool SetupSendStream() {
144 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146 }
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800147 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1))) {
148 return false;
149 }
solenberg059fb442016-10-26 05:12:24 -0700150 EXPECT_CALL(apm_, set_output_will_be_muted(false));
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800151 return channel_->SetAudioSend(kSsrc1, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 }
solenberg8189b022016-06-14 12:13:00 -0700153
154 bool AddRecvStream(uint32_t ssrc) {
155 EXPECT_TRUE(channel_);
156 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
157 }
158
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000159 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700160 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700161 // Remove stream added in Setup.
solenberg3a941542015-11-16 07:34:50 -0800162 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg85a04962015-10-27 03:35:21 -0700163 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
solenberg0a617e22015-10-20 15:49:38 -0700164 // Verify the channel does not exist.
solenberg3a941542015-11-16 07:34:50 -0800165 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000166 }
solenberg8189b022016-06-14 12:13:00 -0700167
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700169 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 }
solenberg8189b022016-06-14 12:13:00 -0700172
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200173 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175 }
176
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100177 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
178 const auto* send_stream = call_.GetAudioSendStream(ssrc);
179 EXPECT_TRUE(send_stream);
180 return *send_stream;
181 }
182
deadbeef884f5852016-01-15 09:20:04 -0800183 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
184 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
185 EXPECT_TRUE(recv_stream);
186 return *recv_stream;
187 }
188
solenberg3a941542015-11-16 07:34:50 -0800189 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800190 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800191 }
192
solenberg7add0582015-11-20 09:59:34 -0800193 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800194 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800195 }
196
solenberg059fb442016-10-26 05:12:24 -0700197 void SetSend(bool enable) {
198 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700199 if (enable) {
200 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
201 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
202 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700203 EXPECT_CALL(apm_, ApplyConfig(testing::_));
204 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700205 }
solenberg059fb442016-10-26 05:12:24 -0700206 channel_->SetSend(enable);
207 }
208
209 void SetSendParameters(const cricket::AudioSendParameters& params) {
210 EXPECT_CALL(apm_, ApplyConfig(testing::_));
211 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
212 ASSERT_TRUE(channel_);
213 EXPECT_TRUE(channel_->SetSendParameters(params));
214 }
215
minyue6b825df2016-10-31 04:08:32 -0700216 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
217 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700218 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
219 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700220 if (enable && options) {
221 EXPECT_CALL(apm_, ApplyConfig(testing::_));
222 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
223 }
224 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700225 }
226
solenbergffbbcac2016-11-17 05:25:37 -0800227 void TestInsertDtmf(uint32_t ssrc, bool caller,
228 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700229 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000230 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700231 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000232 // send stream.
233 EXPECT_TRUE(channel_->AddSendStream(
234 cricket::StreamParams::CreateLegacy(kSsrc1)));
235 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000236
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700238 SetSendParameters(send_parameters_);
239 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800241 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800242 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700243 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000245
246 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700247 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800248 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000249 EXPECT_TRUE(channel_->AddSendStream(
250 cricket::StreamParams::CreateLegacy(kSsrc1)));
251 }
252
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800254 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100256 // Test send.
257 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
258 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
259 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800260 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100261 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800262 EXPECT_EQ(codec.id, telephone_event.payload_type);
263 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100264 EXPECT_EQ(2, telephone_event.event_code);
265 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 }
267
268 // Test that send bandwidth is set correctly.
269 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000270 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
271 // |expected_result| is the expected result from SetMaxSendBandwidth().
272 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700273 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
274 int max_bitrate,
275 bool expected_result,
276 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200277 cricket::AudioSendParameters parameters;
278 parameters.codecs.push_back(codec);
279 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700280 if (expected_result) {
281 SetSendParameters(parameters);
282 } else {
283 EXPECT_FALSE(channel_->SetSendParameters(parameters));
284 }
minyue7a973442016-10-20 03:27:12 -0700285 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286 }
287
skvlade0d46372016-04-07 22:59:22 -0700288 // Sets the per-stream maximum bitrate limit for the specified SSRC.
289 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700290 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700291 EXPECT_EQ(1UL, parameters.encodings.size());
292
deadbeefe702b302017-02-04 12:09:01 -0800293 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700294 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700295 }
296
solenberg059fb442016-10-26 05:12:24 -0700297 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700298 cricket::AudioSendParameters send_parameters;
299 send_parameters.codecs.push_back(codec);
300 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700301 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700302 }
303
minyue7a973442016-10-20 03:27:12 -0700304 void CheckSendCodec(int32_t ssrc,
305 const char expected_name[],
306 int expected_channels,
307 int expected_bitrate) {
308 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
309 EXPECT_STREQ(expected_name, codec.plname);
310 EXPECT_EQ(expected_channels, codec.channels);
311 EXPECT_EQ(expected_bitrate, codec.rate);
312 }
313
314 int GetOpusMaxPlaybackRate(int32_t ssrc) {
315 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
316 }
317
318 bool GetOpusDtx(int32_t ssrc) {
319 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
320 }
321
322 bool GetCodecFec(int32_t ssrc) {
323 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
324 }
325
skvlade0d46372016-04-07 22:59:22 -0700326 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700327 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
328 }
329
330 int GetCodecPacSize(int32_t ssrc) {
331 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700332 }
333
minyue6b825df2016-10-31 04:08:32 -0700334 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
335 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
336 }
337
skvlade0d46372016-04-07 22:59:22 -0700338 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
339 int global_max,
340 int stream_max,
341 bool expected_result,
342 int expected_codec_bitrate) {
343 // Clear the bitrate limit from the previous test case.
344 EXPECT_TRUE(SetMaxBitrateForStream(kSsrc1, -1));
345
346 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700347 SetGlobalMaxBitrate(codec, global_max);
skvlade0d46372016-04-07 22:59:22 -0700348 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrc1, stream_max));
349
350 // Verify that reading back the parameters gives results
351 // consistent with the Set() result.
352 webrtc::RtpParameters resulting_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700353 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -0700354 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
355 EXPECT_EQ(expected_result ? stream_max : -1,
356 resulting_parameters.encodings[0].max_bitrate_bps);
357
358 // Verify that the codec settings have the expected bitrate.
359 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrc1));
360 }
361
stefan13f1a0a2016-11-30 07:22:58 -0800362 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
363 int expected_min_bitrate_bps,
364 const char* start_bitrate_kbps,
365 int expected_start_bitrate_bps,
366 const char* max_bitrate_kbps,
367 int expected_max_bitrate_bps) {
368 EXPECT_TRUE(SetupSendStream());
369 auto& codecs = send_parameters_.codecs;
370 codecs.clear();
371 codecs.push_back(kOpusCodec);
372 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
373 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
374 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
375 SetSendParameters(send_parameters_);
376
377 EXPECT_EQ(expected_min_bitrate_bps,
378 call_.GetConfig().bitrate_config.min_bitrate_bps);
379 EXPECT_EQ(expected_start_bitrate_bps,
380 call_.GetConfig().bitrate_config.start_bitrate_bps);
381 EXPECT_EQ(expected_max_bitrate_bps,
382 call_.GetConfig().bitrate_config.max_bitrate_bps);
383 }
384
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000385 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700386 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000387
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000388 // Ensure extensions are off by default.
solenberg3a941542015-11-16 07:34:50 -0800389 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000390
391 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700392 send_parameters_.extensions.push_back(
393 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700394 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800395 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000396
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000397 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200398 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700399 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800400 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000401
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000402 // Ensure extension is set properly.
403 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700404 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700405 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800406 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700407 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800408 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000409
solenberg7add0582015-11-20 09:59:34 -0800410 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000411 EXPECT_TRUE(channel_->AddSendStream(
solenberg0a617e22015-10-20 15:49:38 -0700412 cricket::StreamParams::CreateLegacy(kSsrc2)));
solenberg3a941542015-11-16 07:34:50 -0800413 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
414 call_.GetAudioSendStream(kSsrc2));
415 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700416 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800417 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000418
419 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200420 send_parameters_.codecs.push_back(kPcmuCodec);
421 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700422 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800423 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
424 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000425 }
426
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000427 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700428 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000429
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000430 // Ensure extensions are off by default.
solenberg7add0582015-11-20 09:59:34 -0800431 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000432
433 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700434 recv_parameters_.extensions.push_back(
435 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800436 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
437 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000438
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000439 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800440 recv_parameters_.extensions.clear();
441 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
442 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000443
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000444 // Ensure extension is set properly.
445 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700446 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800447 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
448 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700449 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800450 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000451
solenberg7add0582015-11-20 09:59:34 -0800452 // Ensure extension is set properly on new stream.
solenberg8189b022016-06-14 12:13:00 -0700453 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -0800454 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
455 call_.GetAudioReceiveStream(kSsrc2));
456 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700457 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800458 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000459
460 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800461 recv_parameters_.extensions.clear();
462 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
463 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
464 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000465 }
466
solenberg85a04962015-10-27 03:35:21 -0700467 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
468 webrtc::AudioSendStream::Stats stats;
469 stats.local_ssrc = 12;
470 stats.bytes_sent = 345;
471 stats.packets_sent = 678;
472 stats.packets_lost = 9012;
473 stats.fraction_lost = 34.56f;
474 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800475 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700476 stats.ext_seqnum = 789;
477 stats.jitter_ms = 12;
478 stats.rtt_ms = 345;
479 stats.audio_level = 678;
480 stats.aec_quality_min = 9.01f;
481 stats.echo_delay_median_ms = 234;
482 stats.echo_delay_std_ms = 567;
483 stats.echo_return_loss = 890;
484 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700485 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800486 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700487 stats.typing_noise_detected = true;
488 return stats;
489 }
490 void SetAudioSendStreamStats() {
491 for (auto* s : call_.GetAudioSendStreams()) {
492 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200493 }
solenberg85a04962015-10-27 03:35:21 -0700494 }
solenberg566ef242015-11-06 15:34:49 -0800495 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
496 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700497 const auto stats = GetAudioSendStreamStats();
498 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
499 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
500 EXPECT_EQ(info.packets_sent, stats.packets_sent);
501 EXPECT_EQ(info.packets_lost, stats.packets_lost);
502 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
503 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800504 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700505 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
506 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
507 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
508 EXPECT_EQ(info.audio_level, stats.audio_level);
509 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
510 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
511 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
512 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
513 EXPECT_EQ(info.echo_return_loss_enhancement,
514 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700515 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800516 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
517 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800518 EXPECT_EQ(info.typing_noise_detected,
519 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700520 }
521
522 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
523 webrtc::AudioReceiveStream::Stats stats;
524 stats.remote_ssrc = 123;
525 stats.bytes_rcvd = 456;
526 stats.packets_rcvd = 768;
527 stats.packets_lost = 101;
528 stats.fraction_lost = 23.45f;
529 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800530 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700531 stats.ext_seqnum = 678;
532 stats.jitter_ms = 901;
533 stats.jitter_buffer_ms = 234;
534 stats.jitter_buffer_preferred_ms = 567;
535 stats.delay_estimate_ms = 890;
536 stats.audio_level = 1234;
537 stats.expand_rate = 5.67f;
538 stats.speech_expand_rate = 8.90f;
539 stats.secondary_decoded_rate = 1.23f;
540 stats.accelerate_rate = 4.56f;
541 stats.preemptive_expand_rate = 7.89f;
542 stats.decoding_calls_to_silence_generator = 12;
543 stats.decoding_calls_to_neteq = 345;
544 stats.decoding_normal = 67890;
545 stats.decoding_plc = 1234;
546 stats.decoding_cng = 5678;
547 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700548 stats.decoding_muted_output = 3456;
549 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200550 return stats;
551 }
552 void SetAudioReceiveStreamStats() {
553 for (auto* s : call_.GetAudioReceiveStreams()) {
554 s->SetStats(GetAudioReceiveStreamStats());
555 }
556 }
557 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700558 const auto stats = GetAudioReceiveStreamStats();
559 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
560 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
561 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
562 EXPECT_EQ(info.packets_lost, stats.packets_lost);
563 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
564 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800565 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700566 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
567 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
568 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200569 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700570 stats.jitter_buffer_preferred_ms);
571 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
572 EXPECT_EQ(info.audio_level, stats.audio_level);
573 EXPECT_EQ(info.expand_rate, stats.expand_rate);
574 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
575 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
576 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
577 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200578 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700579 stats.decoding_calls_to_silence_generator);
580 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
581 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
582 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
583 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
584 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700585 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700586 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200587 }
hbos1acfbd22016-11-17 23:43:29 -0800588 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
589 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
590 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
591 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
592 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
593 codec.ToCodecParameters());
594 }
595 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
596 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
597 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
598 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
599 codec.ToCodecParameters());
600 }
601 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200602
peah8271d042016-11-22 07:24:52 -0800603 bool IsHighPassFilterEnabled() {
604 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
605 }
606
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000607 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700608 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700609 StrictMock<webrtc::test::MockAudioProcessing> apm_;
skvlad11a9cbf2016-10-07 11:53:05 -0700610 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200611 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000612 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700613 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700614 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200615 cricket::AudioSendParameters send_parameters_;
616 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800617 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800618 private:
619 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620};
621
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000622// Tests that we can create and destroy a channel.
623TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700624 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000625}
626
solenberg31fec402016-05-06 02:13:12 -0700627// Test that we can add a send stream and that it has the correct defaults.
628TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
629 EXPECT_TRUE(SetupChannel());
630 EXPECT_TRUE(
631 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
632 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrc1);
633 EXPECT_EQ(kSsrc1, config.rtp.ssrc);
634 EXPECT_EQ("", config.rtp.c_name);
635 EXPECT_EQ(0u, config.rtp.extensions.size());
636 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
637 config.send_transport);
638}
639
640// Test that we can add a receive stream and that it has the correct defaults.
641TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
642 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -0700643 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg31fec402016-05-06 02:13:12 -0700644 const webrtc::AudioReceiveStream::Config& config =
645 GetRecvStreamConfig(kSsrc1);
646 EXPECT_EQ(kSsrc1, config.rtp.remote_ssrc);
647 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
648 EXPECT_FALSE(config.rtp.transport_cc);
649 EXPECT_EQ(0u, config.rtp.extensions.size());
650 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
651 config.rtcp_send_transport);
652 EXPECT_EQ("", config.sync_group);
653}
654
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700656// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700657// TODO(ossu): This test should move into a separate builtin audio codecs
658// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700659TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700660 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661 ASSERT_FALSE(codecs.empty());
662 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
663 EXPECT_EQ(48000, codecs[0].clockrate);
664 EXPECT_EQ(2, codecs[0].channels);
665 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000666}
667
stefanba4c0e42016-02-04 04:12:24 -0800668TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700669 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800670 bool opus_found = false;
671 for (cricket::AudioCodec codec : codecs) {
672 if (codec.name == "opus") {
673 EXPECT_TRUE(HasTransportCc(codec));
674 opus_found = true;
675 }
676 }
677 EXPECT_TRUE(opus_found);
678}
679
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680// Tests that we can find codecs by name or id, and that we interpret the
681// clockrate and bitrate fields properly.
682TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
683 cricket::AudioCodec codec;
684 webrtc::CodecInst codec_inst;
685 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800686 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800688 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800690 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
691 &codec_inst));
692 // Find telephone-event with explicit clockrate and 0 bitrate.
693 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800694 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 // Find ISAC with a different payload id.
696 codec = kIsacCodec;
697 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800698 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 EXPECT_EQ(codec.id, codec_inst.pltype);
700 // Find PCMU with a 0 clockrate.
701 codec = kPcmuCodec;
702 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800703 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704 EXPECT_EQ(codec.id, codec_inst.pltype);
705 EXPECT_EQ(8000, codec_inst.plfreq);
706 // Find PCMU with a 0 bitrate.
707 codec = kPcmuCodec;
708 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800709 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710 EXPECT_EQ(codec.id, codec_inst.pltype);
711 EXPECT_EQ(64000, codec_inst.rate);
712 // Find ISAC with an explicit bitrate.
713 codec = kIsacCodec;
714 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800715 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716 EXPECT_EQ(codec.id, codec_inst.pltype);
717 EXPECT_EQ(32000, codec_inst.rate);
718}
719
720// Test that we set our inbound codecs properly, including changing PT.
721TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700722 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200723 cricket::AudioRecvParameters parameters;
724 parameters.codecs.push_back(kIsacCodec);
725 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800726 parameters.codecs.push_back(kTelephoneEventCodec1);
727 parameters.codecs.push_back(kTelephoneEventCodec2);
728 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200729 parameters.codecs[2].id = 126;
730 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700731 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700732 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800733
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800735 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736 gcodec.plfreq = 16000;
737 gcodec.channels = 1;
738 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
739 EXPECT_EQ(106, gcodec.pltype);
740 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800741
tfarina5237aaf2015-11-10 23:44:30 -0800742 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 gcodec.plfreq = 8000;
744 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
745 EXPECT_EQ(126, gcodec.pltype);
746 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800747
748 gcodec.plfreq = 32000;
749 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
750 EXPECT_EQ(107, gcodec.pltype);
751 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000752}
753
754// Test that we fail to set an unknown inbound codec.
755TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700756 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200757 cricket::AudioRecvParameters parameters;
758 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700759 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200760 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761}
762
763// Test that we fail if we have duplicate types in the inbound list.
764TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700765 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200766 cricket::AudioRecvParameters parameters;
767 parameters.codecs.push_back(kIsacCodec);
768 parameters.codecs.push_back(kCn16000Codec);
769 parameters.codecs[1].id = kIsacCodec.id;
770 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771}
772
773// Test that we can decode OPUS without stereo parameters.
774TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700775 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200776 cricket::AudioRecvParameters parameters;
777 parameters.codecs.push_back(kIsacCodec);
778 parameters.codecs.push_back(kPcmuCodec);
779 parameters.codecs.push_back(kOpusCodec);
780 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700781 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700782 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800784 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785 // Even without stereo parameters, recv codecs still specify channels = 2.
786 EXPECT_EQ(2, opus.channels);
787 EXPECT_EQ(111, opus.pltype);
788 EXPECT_STREQ("opus", opus.plname);
789 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700790 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 EXPECT_EQ(111, opus.pltype);
792}
793
794// Test that we can decode OPUS with stereo = 0.
795TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700796 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 cricket::AudioRecvParameters parameters;
798 parameters.codecs.push_back(kIsacCodec);
799 parameters.codecs.push_back(kPcmuCodec);
800 parameters.codecs.push_back(kOpusCodec);
801 parameters.codecs[2].params["stereo"] = "0";
802 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700803 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804 int channel_num2 = voe_.GetLastChannel();
805 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800806 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 // Even when stereo is off, recv codecs still specify channels = 2.
808 EXPECT_EQ(2, opus.channels);
809 EXPECT_EQ(111, opus.pltype);
810 EXPECT_STREQ("opus", opus.plname);
811 opus.pltype = 0;
812 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
813 EXPECT_EQ(111, opus.pltype);
814}
815
816// Test that we can decode OPUS with stereo = 1.
817TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700818 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200819 cricket::AudioRecvParameters parameters;
820 parameters.codecs.push_back(kIsacCodec);
821 parameters.codecs.push_back(kPcmuCodec);
822 parameters.codecs.push_back(kOpusCodec);
823 parameters.codecs[2].params["stereo"] = "1";
824 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700825 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826 int channel_num2 = voe_.GetLastChannel();
827 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800828 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 EXPECT_EQ(2, opus.channels);
830 EXPECT_EQ(111, opus.pltype);
831 EXPECT_STREQ("opus", opus.plname);
832 opus.pltype = 0;
833 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
834 EXPECT_EQ(111, opus.pltype);
835}
836
837// Test that changes to recv codecs are applied to all streams.
838TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700839 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 cricket::AudioRecvParameters parameters;
841 parameters.codecs.push_back(kIsacCodec);
842 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800843 parameters.codecs.push_back(kTelephoneEventCodec1);
844 parameters.codecs.push_back(kTelephoneEventCodec2);
845 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 parameters.codecs[2].id = 126;
847 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700848 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800850
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800852 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 gcodec.plfreq = 16000;
854 gcodec.channels = 1;
855 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
856 EXPECT_EQ(106, gcodec.pltype);
857 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800858
tfarina5237aaf2015-11-10 23:44:30 -0800859 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860 gcodec.plfreq = 8000;
861 gcodec.channels = 1;
862 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
863 EXPECT_EQ(126, gcodec.pltype);
864 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800865
866 gcodec.plfreq = 32000;
867 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
868 EXPECT_EQ(107, gcodec.pltype);
869 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870}
871
872TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700873 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200874 cricket::AudioRecvParameters parameters;
875 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800876 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200877 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878
kwibergd32bf752017-01-19 07:03:59 -0800879 const auto& dm = GetRecvStreamConfig(kSsrc1).decoder_map;
880 ASSERT_EQ(1, dm.count(106));
881 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882}
883
884// Test that we can apply the same set of codecs again while playing.
885TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700886 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 cricket::AudioRecvParameters parameters;
888 parameters.codecs.push_back(kIsacCodec);
889 parameters.codecs.push_back(kCn16000Codec);
890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700891 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893
894 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200895 parameters.codecs[0].id = 127;
896 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700897 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898}
899
900// Test that we can add a codec while playing.
901TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700902 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 cricket::AudioRecvParameters parameters;
904 parameters.codecs.push_back(kIsacCodec);
905 parameters.codecs.push_back(kCn16000Codec);
906 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700907 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200909 parameters.codecs.push_back(kOpusCodec);
910 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700911 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800913 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
915}
916
917TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700918 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000920 // Test that when autobw is enabled, bitrate is kept as the default
921 // value. autobw is enabled for the following tests because the target
922 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923
924 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700925 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926
927 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700928 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700931 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932}
933
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000934TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000937 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938
939 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700940 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
941 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
942 // Rates above the max (56000) should be capped.
943 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700946 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
947 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
948 // Rates above the max (510000) should be capped.
949 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000952TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700953 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954
955 // Test that we can only set a maximum bitrate for a fixed-rate codec
956 // if it's bigger than the fixed rate.
957
958 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
960 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
961 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
962 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
963 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
964 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
965 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966}
967
968TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700969 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200970 const int kDesiredBitrate = 128000;
971 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700972 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200973 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700974 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000975
976 EXPECT_TRUE(channel_->AddSendStream(
977 cricket::StreamParams::CreateLegacy(kSsrc1)));
978
minyue7a973442016-10-20 03:27:12 -0700979 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrc1));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000980}
981
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982// Test that bitrate cannot be set for CBR codecs.
983// Bitrate is ignored if it is higher than the fixed bitrate.
984// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987
988 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700989 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700990 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200991
992 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700993 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -0700994 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200995
996 send_parameters_.max_bandwidth_bps = 128;
997 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
minyue7a973442016-10-20 03:27:12 -0700998 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999}
1000
skvlade0d46372016-04-07 22:59:22 -07001001// Test that the per-stream bitrate limit and the global
1002// bitrate limit both apply.
1003TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1004 EXPECT_TRUE(SetupSendStream());
1005
1006 // opus, default bitrate == 64000.
1007 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1008 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1009 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1010 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1011
1012 // CBR codecs allow both maximums to exceed the bitrate.
1013 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1014 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1015 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1016 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1017
1018 // CBR codecs don't allow per stream maximums to be too low.
1019 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1020 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1021}
1022
1023// Test that an attempt to set RtpParameters for a stream that does not exist
1024// fails.
1025TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1026 EXPECT_TRUE(SetupChannel());
1027 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001028 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001029 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1030
1031 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001032 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001033}
1034
1035TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001036 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001037 // This test verifies that setting RtpParameters succeeds only if
1038 // the structure contains exactly one encoding.
1039 // TODO(skvlad): Update this test when we start supporting setting parameters
1040 // for each encoding individually.
1041
1042 EXPECT_TRUE(SetupSendStream());
deadbeeffb2aced2017-01-06 23:05:37 -08001043 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001044 // Two or more encodings should result in failure.
1045 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001046 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001047 // Zero encodings should also fail.
1048 parameters.encodings.clear();
1049 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
1050}
1051
1052// Changing the SSRC through RtpParameters is not allowed.
1053TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1054 EXPECT_TRUE(SetupSendStream());
1055 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
1056 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
1057 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -07001058}
1059
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001060// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001061// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001062TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1063 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001064 SetSend(true);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001065 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1066 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001067 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001068 ASSERT_EQ(1u, parameters.encodings.size());
1069 ASSERT_TRUE(parameters.encodings[0].active);
1070 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001071 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001072 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
1073
1074 // Now change it back to active and verify we resume sending.
1075 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001076 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001077 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1078}
1079
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001080// Test that SetRtpSendParameters configures the correct encoding channel for
1081// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001082TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1083 SetupForMultiSendStream();
1084 // Create send streams.
1085 for (uint32_t ssrc : kSsrcs4) {
1086 EXPECT_TRUE(
1087 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1088 }
1089 // Configure one stream to be limited by the stream config, another to be
1090 // limited by the global max, and the third one with no per-stream limit
1091 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001092 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001093 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1094 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1095 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1096
1097 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1098 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1099 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1100
1101 // Remove the global cap; the streams should switch to their respective
1102 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001103 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001104 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1105 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1106 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1107}
1108
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001109// Test that GetRtpSendParameters returns the currently configured codecs.
1110TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001111 EXPECT_TRUE(SetupSendStream());
1112 cricket::AudioSendParameters parameters;
1113 parameters.codecs.push_back(kIsacCodec);
1114 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001115 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001116
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001117 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001118 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001119 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1120 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001121}
1122
deadbeefcb443432016-12-12 11:12:36 -08001123// Test that GetRtpSendParameters returns an SSRC.
1124TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1125 EXPECT_TRUE(SetupSendStream());
1126 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
1127 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1128 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1129}
1130
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001132TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001133 EXPECT_TRUE(SetupSendStream());
1134 cricket::AudioSendParameters parameters;
1135 parameters.codecs.push_back(kIsacCodec);
1136 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001137 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001140
1141 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001142 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001144 // ... And this shouldn't change the params returned by GetRtpSendParameters.
1145 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrc1);
1146 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrc1));
1147}
1148
1149// Test that GetRtpReceiveParameters returns the currently configured codecs.
1150TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1151 EXPECT_TRUE(SetupRecvStream());
1152 cricket::AudioRecvParameters parameters;
1153 parameters.codecs.push_back(kIsacCodec);
1154 parameters.codecs.push_back(kPcmuCodec);
1155 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1156
1157 webrtc::RtpParameters rtp_parameters =
1158 channel_->GetRtpReceiveParameters(kSsrc1);
1159 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1160 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1161 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1162}
1163
deadbeefcb443432016-12-12 11:12:36 -08001164// Test that GetRtpReceiveParameters returns an SSRC.
1165TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1166 EXPECT_TRUE(SetupRecvStream());
1167 webrtc::RtpParameters rtp_parameters =
1168 channel_->GetRtpReceiveParameters(kSsrc1);
1169 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1170 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1171}
1172
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001173// Test that if we set/get parameters multiple times, we get the same results.
1174TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1175 EXPECT_TRUE(SetupRecvStream());
1176 cricket::AudioRecvParameters parameters;
1177 parameters.codecs.push_back(kIsacCodec);
1178 parameters.codecs.push_back(kPcmuCodec);
1179 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1180
1181 webrtc::RtpParameters initial_params =
1182 channel_->GetRtpReceiveParameters(kSsrc1);
1183
1184 // We should be able to set the params we just got.
1185 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrc1, initial_params));
1186
1187 // ... And this shouldn't change the params returned by
1188 // GetRtpReceiveParameters.
1189 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrc1);
1190 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrc1));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001191}
1192
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001193// Test that we apply codecs properly.
1194TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001195 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001196 cricket::AudioSendParameters parameters;
1197 parameters.codecs.push_back(kIsacCodec);
1198 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001199 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001200 parameters.codecs[0].id = 96;
1201 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001202 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001203 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001204 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
1205 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1206 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1207 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1208 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1209 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1210 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1211 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001212 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001213}
1214
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001215// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1216// to apply.
1217TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001218 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001219 cricket::AudioSendParameters parameters;
1220 parameters.codecs.push_back(kIsacCodec);
1221 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001222 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001223 parameters.codecs[0].id = 96;
1224 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001225 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001226 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001227 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001228 // Calling SetSendCodec again with same codec which is already set.
1229 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001230 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001231 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001232}
1233
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001234// Verify that G722 is set with 16000 samples per second to WebRTC.
1235TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001236 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001237 cricket::AudioSendParameters parameters;
1238 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001239 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001240 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001241 EXPECT_STREQ("G722", gcodec.plname);
1242 EXPECT_EQ(1, gcodec.channels);
1243 EXPECT_EQ(16000, gcodec.plfreq);
1244}
1245
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001246// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001247TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001248 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001249 cricket::AudioSendParameters parameters;
1250 parameters.codecs.push_back(kOpusCodec);
1251 parameters.codecs[0].bitrate = 0;
1252 parameters.codecs[0].clockrate = 50000;
1253 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001254}
1255
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001256// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001257TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001258 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001259 cricket::AudioSendParameters parameters;
1260 parameters.codecs.push_back(kOpusCodec);
1261 parameters.codecs[0].bitrate = 0;
1262 parameters.codecs[0].channels = 0;
1263 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001264}
1265
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001266// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001267TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001268 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001269 cricket::AudioSendParameters parameters;
1270 parameters.codecs.push_back(kOpusCodec);
1271 parameters.codecs[0].bitrate = 0;
1272 parameters.codecs[0].channels = 0;
1273 parameters.codecs[0].params["stereo"] = "1";
1274 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001275}
1276
1277// Test that if channel is 1 for opus and there's no stereo, we fail.
1278TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001279 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001280 cricket::AudioSendParameters parameters;
1281 parameters.codecs.push_back(kOpusCodec);
1282 parameters.codecs[0].bitrate = 0;
1283 parameters.codecs[0].channels = 1;
1284 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285}
1286
1287// Test that if channel is 1 for opus and stereo=0, we fail.
1288TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001289 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001290 cricket::AudioSendParameters parameters;
1291 parameters.codecs.push_back(kOpusCodec);
1292 parameters.codecs[0].bitrate = 0;
1293 parameters.codecs[0].channels = 1;
1294 parameters.codecs[0].params["stereo"] = "0";
1295 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001296}
1297
1298// Test that if channel is 1 for opus and stereo=1, we fail.
1299TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001300 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001301 cricket::AudioSendParameters parameters;
1302 parameters.codecs.push_back(kOpusCodec);
1303 parameters.codecs[0].bitrate = 0;
1304 parameters.codecs[0].channels = 1;
1305 parameters.codecs[0].params["stereo"] = "1";
1306 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307}
1308
1309// Test that with bitrate=0 and no stereo,
1310// channels and bitrate are 1 and 32000.
1311TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001312 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001313 cricket::AudioSendParameters parameters;
1314 parameters.codecs.push_back(kOpusCodec);
1315 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001316 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001317 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001318}
1319
1320// Test that with bitrate=0 and stereo=0,
1321// channels and bitrate are 1 and 32000.
1322TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001323 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001324 cricket::AudioSendParameters parameters;
1325 parameters.codecs.push_back(kOpusCodec);
1326 parameters.codecs[0].bitrate = 0;
1327 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001328 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001329 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330}
1331
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001332// Test that with bitrate=invalid and stereo=0,
1333// channels and bitrate are 1 and 32000.
1334TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001335 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001336 cricket::AudioSendParameters parameters;
1337 parameters.codecs.push_back(kOpusCodec);
1338 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001339 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001341 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001342 CheckSendCodec(kSsrc1, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001343
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001344 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001345 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001346 CheckSendCodec(kSsrc1, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001347}
1348
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001349// Test that with bitrate=0 and stereo=1,
1350// channels and bitrate are 2 and 64000.
1351TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001352 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001353 cricket::AudioSendParameters parameters;
1354 parameters.codecs.push_back(kOpusCodec);
1355 parameters.codecs[0].bitrate = 0;
1356 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001357 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001358 CheckSendCodec(kSsrc1, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001359}
1360
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001361// Test that with bitrate=invalid and stereo=1,
1362// channels and bitrate are 2 and 64000.
1363TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001364 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001365 cricket::AudioSendParameters parameters;
1366 parameters.codecs.push_back(kOpusCodec);
1367 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001368 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001370 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001371 CheckSendCodec(kSsrc1, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001372
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001374 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001375 CheckSendCodec(kSsrc1, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001376}
1377
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001378// Test that with bitrate=N and stereo unset,
1379// channels and bitrate are 1 and N.
1380TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001381 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001385 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001386 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387 EXPECT_EQ(111, gcodec.pltype);
1388 EXPECT_EQ(96000, gcodec.rate);
1389 EXPECT_STREQ("opus", gcodec.plname);
1390 EXPECT_EQ(1, gcodec.channels);
1391 EXPECT_EQ(48000, gcodec.plfreq);
1392}
1393
1394// Test that with bitrate=N and stereo=0,
1395// channels and bitrate are 1 and N.
1396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].bitrate = 30000;
1401 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001402 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001403 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404}
1405
1406// Test that with bitrate=N and without any parameters,
1407// channels and bitrate are 1 and N.
1408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001409 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 cricket::AudioSendParameters parameters;
1411 parameters.codecs.push_back(kOpusCodec);
1412 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001414 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
1417// Test that with bitrate=N and stereo=1,
1418// channels and bitrate are 2 and N.
1419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 30000;
1424 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001426 CheckSendCodec(kSsrc1, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001427}
1428
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001429// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1430// Also test that the "maxaveragebitrate" can't be set to values outside the
1431// range of 6000 and 510000
1432TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001433 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001434 cricket::AudioSendParameters parameters;
1435 parameters.codecs.push_back(kOpusCodec);
1436 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001440 EXPECT_EQ(6000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001441
1442 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001445 EXPECT_EQ(510000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001446
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001448 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001449 EXPECT_EQ(200000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001450}
1451
stefan13f1a0a2016-11-30 07:22:58 -08001452TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1453 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1454 200000);
1455}
1456
1457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1458 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1459}
1460
1461TEST_F(WebRtcVoiceEngineTestFake,
1462 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1463 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1464}
1465
1466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1467 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1468}
1469
1470TEST_F(WebRtcVoiceEngineTestFake,
1471 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1472 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1473 200000);
1474 send_parameters_.max_bandwidth_bps = 300000;
1475 SetSendParameters(send_parameters_);
1476 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1477 << "Setting max bitrate should keep previous min bitrate.";
1478 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1479 << "Setting max bitrate should not reset start bitrate.";
1480 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1481}
1482
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001483// Test that we can enable NACK with opus as caller.
1484TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001485 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001486 cricket::AudioSendParameters parameters;
1487 parameters.codecs.push_back(kOpusCodec);
1488 parameters.codecs[0].AddFeedbackParam(
1489 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1490 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001491 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001492 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001493 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494}
1495
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001496// Test that we can enable NACK with opus as callee.
1497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].AddFeedbackParam(
1502 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1503 cricket::kParamValueEmpty));
solenberg8189b022016-06-14 12:13:00 -07001504 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001505 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001506 // NACK should be enabled even with no send stream.
solenberg8189b022016-06-14 12:13:00 -07001507 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001508
1509 EXPECT_TRUE(channel_->AddSendStream(
1510 cricket::StreamParams::CreateLegacy(kSsrc1)));
solenberg971cab02016-06-14 10:02:41 -07001511 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001512}
1513
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514// Test that we can enable NACK on receive streams.
1515TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001516 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001517 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].AddFeedbackParam(
1521 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1522 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001523 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001524 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001526 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001527 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528}
1529
1530// Test that we can disable NACK.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001538 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001539 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001540
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 parameters.codecs.clear();
1542 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001544 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001545}
1546
1547// Test that we can disable NACK on receive streams.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001550 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].AddFeedbackParam(
1554 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1555 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001557 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001558 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001560 parameters.codecs.clear();
1561 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001563 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001564 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565}
1566
1567// Test that NACK is enabled on a new receive stream.
1568TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001569 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001570 cricket::AudioSendParameters parameters;
1571 parameters.codecs.push_back(kIsacCodec);
1572 parameters.codecs.push_back(kCn16000Codec);
1573 parameters.codecs[0].AddFeedbackParam(
1574 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1575 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001577 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578
solenberg8189b022016-06-14 12:13:00 -07001579 EXPECT_TRUE(AddRecvStream(kSsrc2));
1580 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
1581 EXPECT_TRUE(AddRecvStream(kSsrc3));
1582 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc3).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001585// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001587 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 cricket::AudioSendParameters parameters;
1589 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001591 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001592}
1593
1594// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001597 cricket::AudioSendParameters parameters;
1598 parameters.codecs.push_back(kOpusCodec);
1599 parameters.codecs[0].bitrate = 0;
1600 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001601 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001602 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001603}
1604
1605// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001606TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 cricket::AudioSendParameters parameters;
1609 parameters.codecs.push_back(kOpusCodec);
1610 parameters.codecs[0].bitrate = 0;
1611 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001613 EXPECT_TRUE(GetCodecFec(kSsrc1));
1614 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001615}
1616
1617// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001618TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001619 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001620 cricket::AudioSendParameters parameters;
1621 parameters.codecs.push_back(kOpusCodec);
1622 parameters.codecs[0].bitrate = 0;
1623 parameters.codecs[0].params["stereo"] = "1";
1624 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001626 EXPECT_TRUE(GetCodecFec(kSsrc1));
1627 CheckSendCodec(kSsrc1, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001628}
1629
1630// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001633 cricket::AudioSendParameters parameters;
1634 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001636 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001637}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001638
1639// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1640TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001641 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001642 cricket::AudioSendParameters parameters;
1643 parameters.codecs.push_back(kIsacCodec);
1644 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001645 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001646 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001647}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001648
1649// Test that Opus FEC status can be changed.
1650TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001651 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001652 cricket::AudioSendParameters parameters;
1653 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001655 EXPECT_FALSE(GetCodecFec(kSsrc1));
1656
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001657 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001659 EXPECT_TRUE(GetCodecFec(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001660}
1661
stefanba4c0e42016-02-04 04:12:24 -08001662TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001663 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001664 cricket::AudioSendParameters send_parameters;
1665 send_parameters.codecs.push_back(kOpusCodec);
1666 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001667 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001668
1669 cricket::AudioRecvParameters recv_parameters;
1670 recv_parameters.codecs.push_back(kIsacCodec);
1671 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg8189b022016-06-14 12:13:00 -07001672 EXPECT_TRUE(AddRecvStream(kSsrc1));
stefanba4c0e42016-02-04 04:12:24 -08001673 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1674 EXPECT_FALSE(
1675 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1676
ossudedfd282016-06-14 07:12:39 -07001677 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001679 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1680 EXPECT_TRUE(
1681 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1682}
1683
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001684// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1685TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001686 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001687 cricket::AudioSendParameters parameters;
1688 parameters.codecs.push_back(kOpusCodec);
1689 parameters.codecs[0].bitrate = 0;
1690 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001692 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
1693 EXPECT_EQ(12000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001694
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001697 EXPECT_EQ(24000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001698}
1699
1700// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1701TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001702 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 cricket::AudioSendParameters parameters;
1704 parameters.codecs.push_back(kOpusCodec);
1705 parameters.codecs[0].bitrate = 0;
1706 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001708 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrc1));
1709 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001710
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001713 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001714}
1715
1716// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1717TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001718 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001719 cricket::AudioSendParameters parameters;
1720 parameters.codecs.push_back(kOpusCodec);
1721 parameters.codecs[0].bitrate = 0;
1722 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001724 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrc1));
1725 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001726
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001727 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001729 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001730}
1731
1732// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1733TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001734 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters parameters;
1736 parameters.codecs.push_back(kOpusCodec);
1737 parameters.codecs[0].bitrate = 0;
1738 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001740 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrc1));
1741 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001742
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001745 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001746}
1747
1748// Test 24000 < maxplaybackrate triggers Opus full band mode.
1749TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001750 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 cricket::AudioSendParameters parameters;
1752 parameters.codecs.push_back(kOpusCodec);
1753 parameters.codecs[0].bitrate = 0;
1754 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001756 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrc1));
1757 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001758
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001761 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001762}
1763
1764// Test Opus that without maxplaybackrate, default playback rate is used.
1765TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001770 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001771}
1772
1773// Test the with non-Opus, maxplaybackrate has no effect.
1774TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001775 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 cricket::AudioSendParameters parameters;
1777 parameters.codecs.push_back(kIsacCodec);
1778 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001779 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001780 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001781}
1782
1783// Test maxplaybackrate can be set on two streams.
1784TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001785 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001786 cricket::AudioSendParameters parameters;
1787 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001788 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001789 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001790
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001792 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001793 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001794
1795 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
minyue7a973442016-10-20 03:27:12 -07001796 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc2));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001797}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001798
Minyue Li7100dcd2015-03-27 05:05:59 +01001799// Test that with usedtx=0, Opus DTX is off.
1800TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001801 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 cricket::AudioSendParameters parameters;
1803 parameters.codecs.push_back(kOpusCodec);
1804 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001805 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001806 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001807}
1808
1809// Test that with usedtx=1, Opus DTX is on.
1810TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001811 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 cricket::AudioSendParameters parameters;
1813 parameters.codecs.push_back(kOpusCodec);
1814 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001817}
1818
1819// Test that usedtx=1 works with stereo Opus.
1820TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001821 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 cricket::AudioSendParameters parameters;
1823 parameters.codecs.push_back(kOpusCodec);
1824 parameters.codecs[0].params["usedtx"] = "1";
1825 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001827 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001828}
1829
1830// Test that usedtx=1 does not work with non Opus.
1831TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001832 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 cricket::AudioSendParameters parameters;
1834 parameters.codecs.push_back(kIsacCodec);
1835 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001837 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001838}
1839
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001840// Test that we can switch back and forth between Opus and ISAC with CN.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001842 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001843
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 cricket::AudioSendParameters opus_parameters;
1845 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001846 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001847 {
1848 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1849 EXPECT_EQ(111, gcodec.pltype);
1850 EXPECT_STREQ("opus", gcodec.plname);
1851 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001853 cricket::AudioSendParameters isac_parameters;
1854 isac_parameters.codecs.push_back(kIsacCodec);
1855 isac_parameters.codecs.push_back(kCn16000Codec);
1856 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001857 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001858 {
1859 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1860 EXPECT_EQ(103, gcodec.pltype);
1861 EXPECT_STREQ("ISAC", gcodec.plname);
1862 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001863
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001865 {
1866 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1867 EXPECT_EQ(111, gcodec.pltype);
1868 EXPECT_STREQ("opus", gcodec.plname);
1869 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001870}
1871
1872// Test that we handle various ways of specifying bitrate.
1873TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001874 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001875 cricket::AudioSendParameters parameters;
1876 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001877 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001878 {
1879 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1880 EXPECT_EQ(103, gcodec.pltype);
1881 EXPECT_STREQ("ISAC", gcodec.plname);
1882 EXPECT_EQ(32000, gcodec.rate);
1883 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001884
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001885 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001886 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001887 {
1888 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1889 EXPECT_EQ(103, gcodec.pltype);
1890 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001891 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001892 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001893 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001894 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001895 {
1896 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1897 EXPECT_EQ(103, gcodec.pltype);
1898 EXPECT_STREQ("ISAC", gcodec.plname);
1899 EXPECT_EQ(28000, gcodec.rate);
1900 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001902 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001903 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001904 {
1905 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1906 EXPECT_EQ(0, gcodec.pltype);
1907 EXPECT_STREQ("PCMU", gcodec.plname);
1908 EXPECT_EQ(64000, gcodec.rate);
1909 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001913 {
1914 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1915 EXPECT_EQ(0, gcodec.pltype);
1916 EXPECT_STREQ("PCMU", gcodec.plname);
1917 EXPECT_EQ(64000, gcodec.rate);
1918 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001919
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001920 parameters.codecs[0] = kOpusCodec;
1921 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001922 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001923 {
1924 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1925 EXPECT_EQ(111, gcodec.pltype);
1926 EXPECT_STREQ("opus", gcodec.plname);
1927 EXPECT_EQ(32000, gcodec.rate);
1928 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929}
1930
Brave Yao5225dd82015-03-26 07:39:19 +08001931// Test that we could set packet size specified in kCodecParamPTime.
1932TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001933 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 cricket::AudioSendParameters parameters;
1935 parameters.codecs.push_back(kOpusCodec);
1936 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001937 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001938 EXPECT_EQ(1920, GetCodecPacSize(kSsrc1)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001939
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(480, GetCodecPacSize(kSsrc1)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001943
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001945 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001946 EXPECT_EQ(2880, GetCodecPacSize(kSsrc1)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001947
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001948 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1949 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001951 EXPECT_EQ(480, GetCodecPacSize(
1952 kSsrc1)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001953
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001954 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1955 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001956 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001957 EXPECT_EQ(640, GetCodecPacSize(
1958 kSsrc1)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001959}
1960
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001961// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001962TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001963 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001964 cricket::AudioSendParameters parameters;
1965 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001966}
1967
1968// Test that we can set send codecs even with telephone-event codec as the first
1969// one on the list.
1970TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001973 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001974 parameters.codecs.push_back(kIsacCodec);
1975 parameters.codecs.push_back(kPcmuCodec);
1976 parameters.codecs[0].id = 98; // DTMF
1977 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001979 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001980 EXPECT_EQ(96, gcodec.pltype);
1981 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001982 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001983}
1984
solenberg31642aa2016-03-14 08:00:37 -07001985// Test that payload type range is limited for telephone-event codec.
1986TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001987 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001988 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001989 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001990 parameters.codecs.push_back(kIsacCodec);
1991 parameters.codecs[0].id = 0; // DTMF
1992 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001993 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001994 EXPECT_TRUE(channel_->CanInsertDtmf());
1995 parameters.codecs[0].id = 128; // DTMF
1996 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1997 EXPECT_FALSE(channel_->CanInsertDtmf());
1998 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001999 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002000 EXPECT_TRUE(channel_->CanInsertDtmf());
2001 parameters.codecs[0].id = -1; // DTMF
2002 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2003 EXPECT_FALSE(channel_->CanInsertDtmf());
2004}
2005
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002006// Test that we can set send codecs even with CN codec as the first
2007// one on the list.
2008TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002009 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 cricket::AudioSendParameters parameters;
2011 parameters.codecs.push_back(kCn16000Codec);
2012 parameters.codecs.push_back(kIsacCodec);
2013 parameters.codecs.push_back(kPcmuCodec);
2014 parameters.codecs[0].id = 98; // wideband CN
2015 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002017 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2018 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2019 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2020 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2021 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002022}
2023
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002024// Test that we set VAD and DTMF types correctly as caller.
2025TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002026 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002027 cricket::AudioSendParameters parameters;
2028 parameters.codecs.push_back(kIsacCodec);
2029 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002030 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002031 parameters.codecs.push_back(kCn16000Codec);
2032 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002033 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002034 parameters.codecs[0].id = 96;
2035 parameters.codecs[2].id = 97; // wideband CN
2036 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002037 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002038 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2039 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2040 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2041 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2042 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2043 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2044 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002045 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002046}
2047
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002048// Test that we set VAD and DTMF types correctly as callee.
2049TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002050 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002051 cricket::AudioSendParameters parameters;
2052 parameters.codecs.push_back(kIsacCodec);
2053 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002054 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002055 parameters.codecs.push_back(kCn16000Codec);
2056 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002057 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002058 parameters.codecs[0].id = 96;
2059 parameters.codecs[2].id = 97; // wideband CN
2060 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002061 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002062 EXPECT_TRUE(channel_->AddSendStream(
2063 cricket::StreamParams::CreateLegacy(kSsrc1)));
2064
minyue7a973442016-10-20 03:27:12 -07002065 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2066 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2067 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2068 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2069 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2070 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2071 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002072 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002073}
2074
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002075// Test that we only apply VAD if we have a CN codec that matches the
2076// send codec clockrate.
2077TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002078 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002079 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002080 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002081 parameters.codecs.push_back(kIsacCodec);
2082 parameters.codecs.push_back(kCn16000Codec);
2083 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002084 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002085 {
2086 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2087 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2088 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2089 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2090 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2091 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2092 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002093 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002094 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002095 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002096 {
2097 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2098 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2099 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2100 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002101 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002102 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002103 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002104 {
2105 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2106 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2107 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2108 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2109 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2110 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2111 }
Brave Yao5225dd82015-03-26 07:39:19 +08002112 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002113 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002114 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002115 {
2116 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2117 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2118 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2119 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120}
2121
2122// Test that we perform case-insensitive matching of codec names.
2123TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002124 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002125 cricket::AudioSendParameters parameters;
2126 parameters.codecs.push_back(kIsacCodec);
2127 parameters.codecs.push_back(kPcmuCodec);
2128 parameters.codecs.push_back(kCn16000Codec);
2129 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002130 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002131 parameters.codecs[0].name = "iSaC";
2132 parameters.codecs[0].id = 96;
2133 parameters.codecs[2].id = 97; // wideband CN
2134 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002135 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002136 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2137 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2138 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2139 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2140 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2141 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2142 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002143 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002144}
2145
stefanba4c0e42016-02-04 04:12:24 -08002146class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2147 public:
2148 WebRtcVoiceEngineWithSendSideBweTest()
2149 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2150};
2151
2152TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2153 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002154 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002155 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002156 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2157 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2158 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002159 extension.id);
2160 return;
2161 }
2162 }
2163 FAIL() << "Transport sequence number extension not in header-extension list.";
2164}
2165
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002166// Test support for audio level header extension.
2167TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002168 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002169}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002170TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002171 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002172}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002173
solenbergd4adce42016-11-17 06:26:52 -08002174// Test support for transport sequence number header extension.
2175TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2176 TestSetSendRtpHeaderExtensions(
2177 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002178}
solenbergd4adce42016-11-17 06:26:52 -08002179TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2180 TestSetRecvRtpHeaderExtensions(
2181 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002182}
2183
solenberg1ac56142015-10-13 03:58:19 -07002184// Test that we can create a channel and start sending on it.
2185TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002186 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002187 SetSendParameters(send_parameters_);
2188 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002189 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002190 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002191 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2192}
2193
2194// Test that a channel will send if and only if it has a source and is enabled
2195// for sending.
2196TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002197 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002198 SetSendParameters(send_parameters_);
2199 SetAudioSend(kSsrc1, true, nullptr);
2200 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002201 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002202 SetAudioSend(kSsrc1, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002203 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002204 SetAudioSend(kSsrc1, true, nullptr);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002206}
2207
solenberg94218532016-06-16 10:53:22 -07002208// Test that a channel is muted/unmuted.
2209TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2210 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002211 SetSendParameters(send_parameters_);
solenberg94218532016-06-16 10:53:22 -07002212 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002213 SetAudioSend(kSsrc1, true, nullptr);
solenberg94218532016-06-16 10:53:22 -07002214 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002215 SetAudioSend(kSsrc1, false, nullptr);
solenberg94218532016-06-16 10:53:22 -07002216 EXPECT_TRUE(GetSendStream(kSsrc1).muted());
2217}
2218
solenberg6d6e7c52016-04-13 09:07:30 -07002219// Test that SetSendParameters() does not alter a stream's send state.
2220TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2221 EXPECT_TRUE(SetupSendStream());
2222 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2223
2224 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002225 SetSend(true);
solenberg6d6e7c52016-04-13 09:07:30 -07002226 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2227
2228 // Changing RTP header extensions will recreate the AudioSendStream.
2229 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002230 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002231 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002232 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2233
2234 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002235 SetSend(false);
solenberg6d6e7c52016-04-13 09:07:30 -07002236 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2237
2238 // Changing RTP header extensions will recreate the AudioSendStream.
2239 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002240 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002241 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2242}
2243
solenberg1ac56142015-10-13 03:58:19 -07002244// Test that we can create a channel and start playing out on it.
2245TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002246 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002247 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002248 channel_->SetPlayout(true);
2249 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
2250 channel_->SetPlayout(false);
2251 EXPECT_FALSE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002252}
2253
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002254// Test that we can add and remove send streams.
2255TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2256 SetupForMultiSendStream();
2257
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002258 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002259 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002260
solenbergc96df772015-10-21 13:01:53 -07002261 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002262 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002263 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002264 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002265 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002266 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002267 }
tfarina5237aaf2015-11-10 23:44:30 -08002268 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002269
solenbergc96df772015-10-21 13:01:53 -07002270 // Delete the send streams.
2271 for (uint32_t ssrc : kSsrcs4) {
2272 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002273 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002274 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002275 }
solenbergc96df772015-10-21 13:01:53 -07002276 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002277}
2278
2279// Test SetSendCodecs correctly configure the codecs in all send streams.
2280TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2281 SetupForMultiSendStream();
2282
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002283 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002284 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002285 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002286 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002287 }
2288
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002289 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002290 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002291 parameters.codecs.push_back(kIsacCodec);
2292 parameters.codecs.push_back(kCn16000Codec);
2293 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002294 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002295
2296 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002297 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002298 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2299 const auto& send_codec_spec =
2300 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2301 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2302 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2303 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2304 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2305 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002306 }
2307
minyue7a973442016-10-20 03:27:12 -07002308 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002309 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002310 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002311 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002312 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2313 const auto& send_codec_spec =
2314 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2315 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2316 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2317 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2318 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002319 }
2320}
2321
2322// Test we can SetSend on all send streams correctly.
2323TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2324 SetupForMultiSendStream();
2325
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002326 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002327 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002328 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002329 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002330 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002331 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002332 }
2333
2334 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002335 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002336 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002337 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002338 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002339 }
2340
2341 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002342 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002343 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002344 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002345 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002346 }
2347}
2348
2349// Test we can set the correct statistics on all send streams.
2350TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2351 SetupForMultiSendStream();
2352
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002353 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002354 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002356 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002357 }
solenberg85a04962015-10-27 03:35:21 -07002358
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002359 // Create a receive stream to check that none of the send streams end up in
2360 // the receive stream stats.
solenberg8189b022016-06-14 12:13:00 -07002361 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg971cab02016-06-14 10:02:41 -07002362
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002363 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002364 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002365 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002366 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002367
solenberg85a04962015-10-27 03:35:21 -07002368 // Check stats for the added streams.
2369 {
2370 cricket::VoiceMediaInfo info;
2371 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002372
solenberg85a04962015-10-27 03:35:21 -07002373 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002374 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002375 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002376 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002377 }
hbos1acfbd22016-11-17 23:43:29 -08002378 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002379
2380 // We have added one receive stream. We should see empty stats.
2381 EXPECT_EQ(info.receivers.size(), 1u);
2382 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002383 }
solenberg1ac56142015-10-13 03:58:19 -07002384
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002385 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002386 {
2387 cricket::VoiceMediaInfo info;
2388 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2389 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002390 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002391 EXPECT_EQ(0u, info.receivers.size());
2392 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002393
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002394 // Deliver a new packet - a default receive stream should be created and we
2395 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002396 {
2397 cricket::VoiceMediaInfo info;
2398 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2399 SetAudioReceiveStreamStats();
2400 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002401 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002402 EXPECT_EQ(1u, info.receivers.size());
2403 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002404 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002405 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002406}
2407
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002408// Test that we can add and remove receive streams, and do proper send/playout.
2409// We can receive on multiple streams while sending one stream.
2410TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002411 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002412
solenberg1ac56142015-10-13 03:58:19 -07002413 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002414 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002415 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002416
solenberg1ac56142015-10-13 03:58:19 -07002417 // Adding another stream should enable playout on the new stream only.
solenberg8189b022016-06-14 12:13:00 -07002418 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002419 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002420 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421
solenberg1ac56142015-10-13 03:58:19 -07002422 // Make sure only the new stream is played out.
aleloi84ef6152016-08-04 05:28:21 -07002423 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424
2425 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg8189b022016-06-14 12:13:00 -07002426 EXPECT_TRUE(AddRecvStream(kSsrc3));
aleloi84ef6152016-08-04 05:28:21 -07002427 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2428 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429
2430 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002431 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002432 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433
2434 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002435 channel_->SetPlayout(false);
2436 EXPECT_FALSE(GetRecvStream(kSsrc2).started());
2437 EXPECT_FALSE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438
aleloi84ef6152016-08-04 05:28:21 -07002439 // Restart playout and make sure recv streams are played out.
2440 channel_->SetPlayout(true);
2441 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2442 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443
aleloi84ef6152016-08-04 05:28:21 -07002444 // Now remove the recv streams.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2446 EXPECT_TRUE(channel_->RemoveRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447}
2448
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002450// and start sending on it.
2451TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002452 EXPECT_TRUE(SetupSendStream());
solenberg246b8172015-12-08 09:50:23 -08002453 cricket::AudioOptions options_adjust_agc;
2454 options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 webrtc::AgcConfig agc_config;
2456 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2457 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002458 send_parameters_.options = options_adjust_agc;
solenberg059fb442016-10-26 05:12:24 -07002459 SetSendParameters(send_parameters_);
2460 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002461 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2463 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
solenberg059fb442016-10-26 05:12:24 -07002464 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002465 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467}
2468
wu@webrtc.org97077a32013-10-25 21:18:33 +00002469TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002470 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002471 EXPECT_CALL(adm_,
2472 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
wu@webrtc.org97077a32013-10-25 21:18:33 +00002473 webrtc::AgcConfig agc_config;
2474 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2475 EXPECT_EQ(0, agc_config.targetLeveldBOv);
solenberg246b8172015-12-08 09:50:23 -08002476 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2477 send_parameters_.options.tx_agc_digital_compression_gain =
2478 rtc::Optional<uint16_t>(9);
2479 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2480 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002481 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002482 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2483 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2484 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2485 EXPECT_TRUE(agc_config.limiterEnable);
2486
2487 // Check interaction with adjust_agc_delta. Both should be respected, for
2488 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002489 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg059fb442016-10-26 05:12:24 -07002490 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002491 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2492 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2493}
2494
wu@webrtc.org97077a32013-10-25 21:18:33 +00002495TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002496 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002497 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2498 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002499 send_parameters_.options.recording_sample_rate =
2500 rtc::Optional<uint32_t>(48000);
2501 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002502 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002503}
2504
minyue6b825df2016-10-31 04:08:32 -07002505TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2506 EXPECT_TRUE(SetupSendStream());
2507 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2508 send_parameters_.options.audio_network_adaptor_config =
2509 rtc::Optional<std::string>("1234");
2510 SetSendParameters(send_parameters_);
2511 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2512 GetAudioNetworkAdaptorConfig(kSsrc1));
2513}
2514
2515TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2516 EXPECT_TRUE(SetupSendStream());
2517 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2518 send_parameters_.options.audio_network_adaptor_config =
2519 rtc::Optional<std::string>("1234");
2520 SetSendParameters(send_parameters_);
2521 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2522 GetAudioNetworkAdaptorConfig(kSsrc1));
2523 const int initial_num = call_.GetNumCreatedSendStreams();
2524 cricket::AudioOptions options;
2525 options.audio_network_adaptor = rtc::Optional<bool>(false);
2526 SetAudioSend(kSsrc1, true, nullptr, &options);
2527 // AudioSendStream expected to be recreated.
2528 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
2529 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrc1));
2530}
2531
2532TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2533 EXPECT_TRUE(SetupSendStream());
2534 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2535 send_parameters_.options.audio_network_adaptor_config =
2536 rtc::Optional<std::string>("1234");
2537 SetSendParameters(send_parameters_);
2538 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2539 GetAudioNetworkAdaptorConfig(kSsrc1));
2540 const int initial_num = call_.GetNumCreatedSendStreams();
2541 cricket::AudioOptions options;
2542 options.audio_network_adaptor = rtc::Optional<bool>();
2543 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2544 // adaptor.
2545 SetAudioSend(kSsrc1, true, nullptr, &options);
2546 // AudioSendStream not expected to be recreated.
2547 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2548 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2549 GetAudioNetworkAdaptorConfig(kSsrc1));
2550}
2551
michaelt6672b262017-01-11 10:17:59 -08002552class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2553 : public WebRtcVoiceEngineTestFake {
2554 public:
2555 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2556 : WebRtcVoiceEngineTestFake(
2557 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2558 "Enabled/") {}
2559};
2560
2561TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2562 EXPECT_TRUE(SetupSendStream());
2563 cricket::AudioSendParameters parameters;
2564 parameters.codecs.push_back(kOpusCodec);
2565 SetSendParameters(parameters);
2566 const int initial_num = call_.GetNumCreatedSendStreams();
2567 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2568
2569 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2570 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
2571 constexpr int kMinOverheadBps = kOverheadPerPacket * 8 * 1000 / 60;
2572 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2573
2574 constexpr int kOpusMinBitrateBps = 6000;
2575 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
2576 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2577 constexpr int kOpusBitrateFbBps = 32000;
2578 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
2579 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2580
2581 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2582 parameters.options.audio_network_adaptor_config =
2583 rtc::Optional<std::string>("1234");
2584 SetSendParameters(parameters);
2585
2586 constexpr int kMinOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 60;
2587 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2588
2589 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
2590 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2591
2592 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
2593 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2594}
2595
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002596// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002597// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002598TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002599 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002600 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002601}
2602
2603TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2604 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002605 EXPECT_TRUE(SetupSendStream());
solenbergff976312016-03-30 23:28:51 -07002606 // SetupSendStream adds a send stream with kSsrc1, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002607 // stream has to use a different SSRC.
solenberg8189b022016-06-14 12:13:00 -07002608 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002609 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002610 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002611 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002612
solenberg85a04962015-10-27 03:35:21 -07002613 // Check stats for the added streams.
2614 {
2615 cricket::VoiceMediaInfo info;
2616 EXPECT_EQ(true, channel_->GetStats(&info));
2617
2618 // We have added one send stream. We should see the stats we've set.
2619 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002620 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002621 // We have added one receive stream. We should see empty stats.
2622 EXPECT_EQ(info.receivers.size(), 1u);
2623 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2624 }
solenberg1ac56142015-10-13 03:58:19 -07002625
solenberg566ef242015-11-06 15:34:49 -08002626 // Start sending - this affects some reported stats.
2627 {
2628 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002629 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002630 EXPECT_EQ(true, channel_->GetStats(&info));
2631 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002632 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002633 }
2634
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002635 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002636 {
2637 cricket::VoiceMediaInfo info;
2638 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2639 EXPECT_EQ(true, channel_->GetStats(&info));
2640 EXPECT_EQ(1u, info.senders.size());
2641 EXPECT_EQ(0u, info.receivers.size());
2642 }
solenberg1ac56142015-10-13 03:58:19 -07002643
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002644 // Deliver a new packet - a default receive stream should be created and we
2645 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002646 {
2647 cricket::VoiceMediaInfo info;
2648 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2649 SetAudioReceiveStreamStats();
2650 EXPECT_EQ(true, channel_->GetStats(&info));
2651 EXPECT_EQ(1u, info.senders.size());
2652 EXPECT_EQ(1u, info.receivers.size());
2653 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002654 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002655 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002656}
2657
2658// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002659// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002660TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002661 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002662 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg8189b022016-06-14 12:13:00 -07002663 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -08002664 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002665}
2666
2667// Test that the local SSRC is the same on sending and receiving channels if the
2668// receive channel is created before the send channel.
2669TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002670 EXPECT_TRUE(SetupChannel());
solenberg4a0f7b52016-06-16 13:07:33 -07002671 EXPECT_TRUE(AddRecvStream(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002672 EXPECT_TRUE(channel_->AddSendStream(
solenberg4a0f7b52016-06-16 13:07:33 -07002673 cricket::StreamParams::CreateLegacy(kSsrc1)));
2674 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2675 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002676}
2677
2678// Test that we can properly receive packets.
2679TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002680 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002681 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002682 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002683
2684 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2685 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002686}
2687
2688// Test that we can properly receive packets on multiple streams.
2689TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002690 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002691 const uint32_t ssrc1 = 1;
2692 const uint32_t ssrc2 = 2;
2693 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002694 EXPECT_TRUE(AddRecvStream(ssrc1));
2695 EXPECT_TRUE(AddRecvStream(ssrc2));
2696 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002697 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002698 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002699 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002701 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002702 }
mflodman3d7db262016-04-29 00:57:13 -07002703
2704 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2705 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2706 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2707
2708 EXPECT_EQ(s1.received_packets(), 0);
2709 EXPECT_EQ(s2.received_packets(), 0);
2710 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002711
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002712 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002713 EXPECT_EQ(s1.received_packets(), 0);
2714 EXPECT_EQ(s2.received_packets(), 0);
2715 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002716
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002718 EXPECT_EQ(s1.received_packets(), 1);
2719 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2720 EXPECT_EQ(s2.received_packets(), 0);
2721 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002723 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002724 EXPECT_EQ(s1.received_packets(), 1);
2725 EXPECT_EQ(s2.received_packets(), 1);
2726 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2727 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002728
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002730 EXPECT_EQ(s1.received_packets(), 1);
2731 EXPECT_EQ(s2.received_packets(), 1);
2732 EXPECT_EQ(s3.received_packets(), 1);
2733 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002734
mflodman3d7db262016-04-29 00:57:13 -07002735 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2736 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2737 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738}
2739
solenberg7e63ef02015-11-20 00:19:43 -08002740// Test that receiving on an unsignalled stream works (default channel will be
2741// created).
2742TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
solenbergff976312016-03-30 23:28:51 -07002743 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002744 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2745
solenberg7e63ef02015-11-20 00:19:43 -08002746 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002747
2748 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2749 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2750 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002751}
2752
2753// Test that receiving on an unsignalled stream works (default channel will be
2754// created), and that packets will be forwarded to the default channel
2755// regardless of their SSRCs.
2756TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
solenbergff976312016-03-30 23:28:51 -07002757 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002758 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002759 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2760
mflodman3d7db262016-04-29 00:57:13 -07002761 // Note that ssrc = 0 is not supported.
2762 uint32_t ssrc = 1;
2763 for (; ssrc < 10; ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002764 rtc::SetBE32(&packet[8], ssrc);
2765 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002766
2767 // Verify we only have one default stream.
2768 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2769 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2770 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002771 }
mflodman3d7db262016-04-29 00:57:13 -07002772
2773 // Sending the same ssrc again should not create a new stream.
2774 --ssrc;
2775 DeliverPacket(packet, sizeof(packet));
2776 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2777 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2778 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002779}
2780
2781// Test that a default channel is created even after a signalled stream has been
2782// added, and that this stream will get any packets for unknown SSRCs.
2783TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
solenbergff976312016-03-30 23:28:51 -07002784 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002785 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002786 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2787
2788 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002789 const uint32_t signaled_ssrc = 1;
2790 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002791 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002792 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002793 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2794 packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002795
2796 // Note that the first unknown SSRC cannot be 0, because we only support
2797 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002798 const uint32_t unsignaled_ssrc = 7011;
2799 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002800 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002801 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2802 packet, sizeof(packet)));
2803 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2804
2805 DeliverPacket(packet, sizeof(packet));
2806 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2807
2808 rtc::SetBE32(&packet[8], signaled_ssrc);
2809 DeliverPacket(packet, sizeof(packet));
2810 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2811 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002812}
2813
solenberg0a617e22015-10-20 15:49:38 -07002814// Test that we properly handle failures to add a receive stream.
2815TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002816 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002818 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002819}
2820
solenberg0a617e22015-10-20 15:49:38 -07002821// Test that we properly handle failures to add a send stream.
2822TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002823 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002824 voe_.set_fail_create_channel(true);
2825 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2826}
2827
solenberg1ac56142015-10-13 03:58:19 -07002828// Test that AddRecvStream creates new stream.
2829TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002830 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002832 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002833 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002834}
2835
2836// Test that after adding a recv stream, we do not decode more codecs than
2837// those previously passed into SetRecvCodecs.
2838TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002840 cricket::AudioRecvParameters parameters;
2841 parameters.codecs.push_back(kIsacCodec);
2842 parameters.codecs.push_back(kPcmuCodec);
2843 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002844 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002845 int channel_num2 = voe_.GetLastChannel();
2846 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002847 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002848 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849 gcodec.channels = 2;
2850 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2851}
2852
2853// Test that we properly clean up any streams that were added, even if
2854// not explicitly removed.
2855TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002856 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002857 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002858 EXPECT_TRUE(AddRecvStream(1));
2859 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2861 delete channel_;
2862 channel_ = NULL;
2863 EXPECT_EQ(0, voe_.GetNumChannels());
2864}
2865
wu@webrtc.org78187522013-10-07 23:32:02 +00002866TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002867 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002868 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002869}
2870
2871TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002872 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002873 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002874 // Manually delete channel to simulate a failure.
2875 int channel = voe_.GetLastChannel();
2876 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2877 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002878 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002879 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002880 EXPECT_NE(channel, new_channel);
2881 // The last created channel is deleted too.
2882 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002883}
2884
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002885// Test the InsertDtmf on default send stream as caller.
2886TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002887 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002888}
2889
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002890// Test the InsertDtmf on default send stream as callee
2891TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002892 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002893}
2894
2895// Test the InsertDtmf on specified send stream as caller.
2896TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002897 TestInsertDtmf(kSsrc1, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002898}
2899
2900// Test the InsertDtmf on specified send stream as callee.
2901TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002902 TestInsertDtmf(kSsrc1, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002903}
2904
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002906 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002907 EXPECT_CALL(adm_,
2908 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2909 EXPECT_CALL(adm_,
2910 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2911 EXPECT_CALL(adm_,
2912 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913 bool ec_enabled;
2914 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915 webrtc::AecmModes aecm_mode;
2916 bool cng_enabled;
2917 bool agc_enabled;
2918 webrtc::AgcModes agc_mode;
2919 webrtc::AgcConfig agc_config;
2920 bool ns_enabled;
2921 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922 bool stereo_swapping_enabled;
2923 bool typing_detection_enabled;
2924 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925 voe_.GetAecmMode(aecm_mode, cng_enabled);
2926 voe_.GetAgcStatus(agc_enabled, agc_mode);
2927 voe_.GetAgcConfig(agc_config);
2928 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2930 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2931 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002932 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933 EXPECT_FALSE(cng_enabled);
2934 EXPECT_TRUE(agc_enabled);
2935 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2936 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002937 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938 EXPECT_FALSE(stereo_swapping_enabled);
2939 EXPECT_TRUE(typing_detection_enabled);
2940 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2941 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002942 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2943 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002944
solenberg246b8172015-12-08 09:50:23 -08002945 // Nothing set in AudioOptions, so everything should be as default.
2946 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002947 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002948 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949 voe_.GetAecmMode(aecm_mode, cng_enabled);
2950 voe_.GetAgcStatus(agc_enabled, agc_mode);
2951 voe_.GetAgcConfig(agc_config);
2952 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2954 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2955 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002956 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002957 EXPECT_FALSE(cng_enabled);
2958 EXPECT_TRUE(agc_enabled);
2959 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2960 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002961 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962 EXPECT_FALSE(stereo_swapping_enabled);
2963 EXPECT_TRUE(typing_detection_enabled);
2964 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2965 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002966 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2967 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968
2969 // Turn echo cancellation off
solenberg246b8172015-12-08 09:50:23 -08002970 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002971 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 voe_.GetEcStatus(ec_enabled, ec_mode);
2973 EXPECT_FALSE(ec_enabled);
2974
2975 // Turn echo cancellation back on, with settings, and make sure
2976 // nothing else changed.
solenberg246b8172015-12-08 09:50:23 -08002977 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002978 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980 voe_.GetAecmMode(aecm_mode, cng_enabled);
2981 voe_.GetAgcStatus(agc_enabled, agc_mode);
2982 voe_.GetAgcConfig(agc_config);
2983 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2985 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2986 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002987 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002988 EXPECT_TRUE(agc_enabled);
2989 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2990 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002991 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992 EXPECT_FALSE(stereo_swapping_enabled);
2993 EXPECT_TRUE(typing_detection_enabled);
2994 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2995 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2996
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002997 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2998 // control.
solenberg246b8172015-12-08 09:50:23 -08002999 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003000 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003001 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003002 voe_.GetAecmMode(aecm_mode, cng_enabled);
3003 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003004 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003005 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3006
3007 // Turn off echo cancellation and delay agnostic aec.
solenberg246b8172015-12-08 09:50:23 -08003008 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3009 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3010 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003011 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003012 voe_.GetEcStatus(ec_enabled, ec_mode);
3013 EXPECT_FALSE(ec_enabled);
3014 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg246b8172015-12-08 09:50:23 -08003015 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003016 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003017 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003018 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003019 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003020 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3021
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022 // Turn off AGC
solenberg246b8172015-12-08 09:50:23 -08003023 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003024 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025 voe_.GetAgcStatus(agc_enabled, agc_mode);
3026 EXPECT_FALSE(agc_enabled);
3027
3028 // Turn AGC back on
solenberg246b8172015-12-08 09:50:23 -08003029 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3030 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003031 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032 voe_.GetAgcStatus(agc_enabled, agc_mode);
3033 EXPECT_TRUE(agc_enabled);
3034 voe_.GetAgcConfig(agc_config);
3035 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3036
3037 // Turn off other options (and stereo swapping on).
solenberg246b8172015-12-08 09:50:23 -08003038 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3039 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3040 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3041 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003042 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3045 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3046 EXPECT_FALSE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003047 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048 EXPECT_FALSE(typing_detection_enabled);
3049 EXPECT_TRUE(stereo_swapping_enabled);
3050
solenberg1ac56142015-10-13 03:58:19 -07003051 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07003052 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053 voe_.GetEcStatus(ec_enabled, ec_mode);
3054 voe_.GetNsStatus(ns_enabled, ns_mode);
3055 EXPECT_TRUE(ec_enabled);
3056 EXPECT_EQ(webrtc::kEcConference, ec_mode);
3057 EXPECT_FALSE(ns_enabled);
3058 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
3059}
3060
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003061TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
solenbergff976312016-03-30 23:28:51 -07003062 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063
3064 bool ec_enabled;
3065 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066 bool agc_enabled;
3067 webrtc::AgcModes agc_mode;
3068 bool ns_enabled;
3069 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003070 bool stereo_swapping_enabled;
3071 bool typing_detection_enabled;
3072
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003073 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003074 voe_.GetAgcStatus(agc_enabled, agc_mode);
3075 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003076 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3077 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3078 EXPECT_TRUE(ec_enabled);
3079 EXPECT_TRUE(agc_enabled);
3080 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003081 EXPECT_TRUE(IsHighPassFilterEnabled());
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003082 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003084}
3085
3086TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3087 webrtc::AgcConfig set_config = {0};
3088 set_config.targetLeveldBOv = 3;
3089 set_config.digitalCompressionGaindB = 9;
3090 set_config.limiterEnable = true;
3091 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003092
3093 webrtc::AgcConfig config = {0};
3094 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3095 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3096 EXPECT_EQ(set_config.digitalCompressionGaindB,
3097 config.digitalCompressionGaindB);
3098 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3099}
3100
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003101TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003102 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003103 EXPECT_CALL(adm_,
3104 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3105 EXPECT_CALL(adm_,
3106 BuiltInAGCIsAvailable()).Times(9).WillRepeatedly(Return(false));
3107 EXPECT_CALL(adm_,
3108 BuiltInNSIsAvailable()).Times(9).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003109 EXPECT_CALL(adm_,
3110 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3111 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3112 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3113 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3114 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003115
kwiberg686a8ef2016-02-26 03:00:35 -08003116 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003117 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003118 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003119 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003120 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003121 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003122
3123 // Have to add a stream to make SetSend work.
3124 cricket::StreamParams stream1;
3125 stream1.ssrcs.push_back(1);
3126 channel1->AddSendStream(stream1);
3127 cricket::StreamParams stream2;
3128 stream2.ssrcs.push_back(2);
3129 channel2->AddSendStream(stream2);
3130
3131 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003132 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003133 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3134 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3135 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003136 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003137 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003138 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003140
3141 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003142 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003143 parameters_options_no_ns.options.noise_suppression =
3144 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003145 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003146 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003147 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3148 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3149 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003150 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003151
3152 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003153 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003154 parameters_options_no_agc.options.auto_gain_control =
3155 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003156 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003157 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3158 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3159 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003160 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003161
solenberg059fb442016-10-26 05:12:24 -07003162 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003163 bool ec_enabled;
3164 webrtc::EcModes ec_mode;
3165 bool agc_enabled;
3166 webrtc::AgcModes agc_mode;
3167 bool ns_enabled;
3168 webrtc::NsModes ns_mode;
3169 voe_.GetEcStatus(ec_enabled, ec_mode);
3170 voe_.GetAgcStatus(agc_enabled, agc_mode);
3171 voe_.GetNsStatus(ns_enabled, ns_mode);
3172 EXPECT_TRUE(ec_enabled);
3173 EXPECT_TRUE(agc_enabled);
3174 EXPECT_TRUE(ns_enabled);
3175
solenberg059fb442016-10-26 05:12:24 -07003176 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003177 voe_.GetEcStatus(ec_enabled, ec_mode);
3178 voe_.GetAgcStatus(agc_enabled, agc_mode);
3179 voe_.GetNsStatus(ns_enabled, ns_mode);
3180 EXPECT_TRUE(ec_enabled);
3181 EXPECT_TRUE(agc_enabled);
3182 EXPECT_FALSE(ns_enabled);
3183
solenberg059fb442016-10-26 05:12:24 -07003184 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003185 voe_.GetEcStatus(ec_enabled, ec_mode);
3186 voe_.GetAgcStatus(agc_enabled, agc_mode);
3187 voe_.GetNsStatus(ns_enabled, ns_mode);
3188 EXPECT_TRUE(ec_enabled);
3189 EXPECT_FALSE(agc_enabled);
3190 EXPECT_TRUE(ns_enabled);
3191
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003192 // Make sure settings take effect while we are sending.
solenberg059fb442016-10-26 05:12:24 -07003193 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
3194 EXPECT_CALL(apm_, ApplyConfig(testing::_));
3195 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003196 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3197 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003198 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003199 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003200 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003201 rtc::Optional<bool>(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08003202 channel2->SetSend(true);
solenberg059fb442016-10-26 05:12:24 -07003203 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003204 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3205 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3206 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003207 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003208 voe_.GetEcStatus(ec_enabled, ec_mode);
3209 voe_.GetAgcStatus(agc_enabled, agc_mode);
3210 voe_.GetNsStatus(ns_enabled, ns_mode);
3211 EXPECT_TRUE(ec_enabled);
3212 EXPECT_FALSE(agc_enabled);
3213 EXPECT_FALSE(ns_enabled);
3214}
3215
wu@webrtc.orgde305012013-10-31 15:40:38 +00003216// This test verifies DSCP settings are properly applied on voice media channel.
3217TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003218 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003219 cricket::FakeNetworkInterface network_interface;
3220 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003221 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003222
solenberg059fb442016-10-26 05:12:24 -07003223 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3224 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3225
solenbergbc37fc82016-04-04 09:54:44 -07003226 channel.reset(
3227 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003228 channel->SetInterface(&network_interface);
3229 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3230 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3231
3232 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003233 channel.reset(
3234 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003235 channel->SetInterface(&network_interface);
3236 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3237
3238 // Verify that setting the option to false resets the
3239 // DiffServCodePoint.
3240 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003241 channel.reset(
3242 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003243 channel->SetInterface(&network_interface);
3244 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3245 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3246
3247 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003248}
3249
solenberg1ac56142015-10-13 03:58:19 -07003250TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003251 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003252 cricket::WebRtcVoiceMediaChannel* media_channel =
3253 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003254 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003255 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003256 int channel_id = voe_.GetLastChannel();
3257 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3258 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003259 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003260 int channel_id2 = voe_.GetLastChannel();
3261 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003262}
3263
solenberg1ac56142015-10-13 03:58:19 -07003264TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003265 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003266 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003267 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3268 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3269 EXPECT_TRUE(channel_->AddSendStream(
3270 cricket::StreamParams::CreateLegacy(kSsrc1)));
3271 int channel_id = voe_.GetLastChannel();
3272 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3273 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3274 EXPECT_TRUE(channel_->AddSendStream(
3275 cricket::StreamParams::CreateLegacy(kSsrc2)));
3276 int channel_id2 = voe_.GetLastChannel();
3277 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003278}
3279
solenberg4bac9c52015-10-09 02:32:53 -07003280TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003281 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003282 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003283 cricket::StreamParams stream;
3284 stream.ssrcs.push_back(kSsrc2);
3285 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003286 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003287 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003288 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003289}
3290
3291TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003292 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003293 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3294 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003295 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003296 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003297 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3298 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3299 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003300}
3301
pbos8fc7fa72015-07-15 08:02:58 -07003302TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003303 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003304 const std::string kSyncLabel = "AvSyncLabel";
3305
solenbergff976312016-03-30 23:28:51 -07003306 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003307 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3308 sp.sync_label = kSyncLabel;
3309 // Creating two channels to make sure that sync label is set properly for both
3310 // the default voice channel and following ones.
3311 EXPECT_TRUE(channel_->AddRecvStream(sp));
3312 sp.ssrcs[0] += 1;
3313 EXPECT_TRUE(channel_->AddRecvStream(sp));
3314
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003315 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003316 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003317 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003318 << "SyncGroup should be set based on sync_label";
3319 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003320 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003321 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003322}
3323
solenberg3a941542015-11-16 07:34:50 -08003324// TODO(solenberg): Remove, once recv streams are configured through Call.
3325// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003326TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003327 // Test that setting the header extensions results in the expected state
3328 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003329 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003330 ssrcs.push_back(223);
3331 ssrcs.push_back(224);
3332
solenbergff976312016-03-30 23:28:51 -07003333 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003334 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003335 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003336 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003337 cricket::StreamParams::CreateLegacy(ssrc)));
3338 }
3339
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003340 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003341 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003342 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343 EXPECT_NE(nullptr, s);
3344 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3345 }
3346
3347 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003348 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003349 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003350 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003351 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003352 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003353 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003354 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003355 EXPECT_NE(nullptr, s);
3356 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003357 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3358 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003359 for (const auto& s_ext : s_exts) {
3360 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003361 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003362 }
3363 }
3364 }
3365 }
3366
3367 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003368 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003369 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003370 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 EXPECT_NE(nullptr, s);
3372 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3373 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374}
3375
3376TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3377 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003378 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003379 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003380 static const unsigned char kRtcp[] = {
3381 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3382 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3385 };
jbaucheec21bd2016-03-20 06:15:43 -07003386 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003387
solenbergff976312016-03-30 23:28:51 -07003388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003389 cricket::WebRtcVoiceMediaChannel* media_channel =
3390 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003391 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003392 EXPECT_TRUE(media_channel->AddRecvStream(
3393 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3394
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003395 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003396 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003397 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003398 EXPECT_EQ(0, s->received_packets());
3399 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3400 EXPECT_EQ(1, s->received_packets());
3401 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3402 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003403}
Minyue2013aec2015-05-13 14:14:42 +02003404
solenberg0a617e22015-10-20 15:49:38 -07003405// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003406// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003407TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003408 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003409 EXPECT_TRUE(AddRecvStream(kSsrc2));
3410 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3411 EXPECT_TRUE(channel_->AddSendStream(
3412 cricket::StreamParams::CreateLegacy(kSsrc3)));
3413 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3414 EXPECT_TRUE(AddRecvStream(kSsrc4));
3415 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003416}
3417
solenberg7602aab2016-11-14 11:30:07 -08003418TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3419 EXPECT_TRUE(SetupRecvStream());
3420 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3421 EXPECT_TRUE(channel_->AddSendStream(
3422 cricket::StreamParams::CreateLegacy(kSsrc2)));
3423 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3424 EXPECT_TRUE(AddRecvStream(kSsrc3));
3425 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3426 EXPECT_TRUE(channel_->AddSendStream(
3427 cricket::StreamParams::CreateLegacy(kSsrc4)));
3428 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3429 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003430}
stefan658910c2015-09-03 05:48:32 -07003431
deadbeef884f5852016-01-15 09:20:04 -08003432TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003433 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003434 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3435 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003436
3437 // Setting the sink before a recv stream exists should do nothing.
3438 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003439 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003440 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3441
3442 // Now try actually setting the sink.
3443 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3444 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3445
3446 // Now try resetting it.
3447 channel_->SetRawAudioSink(kSsrc1, nullptr);
3448 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3449}
3450
3451TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003452 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003453 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3454 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003455
3456 // Should be able to set a default sink even when no stream exists.
3457 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3458
3459 // Create default channel and ensure it's assigned the default sink.
3460 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3461 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3462
3463 // Try resetting the default sink.
3464 channel_->SetRawAudioSink(0, nullptr);
3465 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3466
3467 // Try setting the default sink while the default stream exists.
3468 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3469 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3470
3471 // If we remove and add a default stream, it should get the same sink.
3472 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3473 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3474 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3475}
3476
skvlad7a43d252016-03-22 15:32:27 -07003477// Test that, just like the video channel, the voice channel communicates the
3478// network state to the call.
3479TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003480 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003481
3482 EXPECT_EQ(webrtc::kNetworkUp,
3483 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3484 EXPECT_EQ(webrtc::kNetworkUp,
3485 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3486
3487 channel_->OnReadyToSend(false);
3488 EXPECT_EQ(webrtc::kNetworkDown,
3489 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3490 EXPECT_EQ(webrtc::kNetworkUp,
3491 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3492
3493 channel_->OnReadyToSend(true);
3494 EXPECT_EQ(webrtc::kNetworkUp,
3495 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3496 EXPECT_EQ(webrtc::kNetworkUp,
3497 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3498}
3499
aleloi18e0b672016-10-04 02:45:47 -07003500// Test that playout is still started after changing parameters
3501TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3502 SetupRecvStream();
3503 channel_->SetPlayout(true);
3504 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3505
3506 // Changing RTP header extensions will recreate the AudioReceiveStream.
3507 cricket::AudioRecvParameters parameters;
3508 parameters.extensions.push_back(
3509 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3510 channel_->SetRecvParameters(parameters);
3511
3512 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3513}
3514
stefan658910c2015-09-03 05:48:32 -07003515// Tests that the library initializes and shuts down properly.
3516TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003517 // If the VoiceEngine wants to gather available codecs early, that's fine but
3518 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003519 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003520 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003521 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003522 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003523 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003524 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3525 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003526 EXPECT_TRUE(channel != nullptr);
3527 delete channel;
solenbergff976312016-03-30 23:28:51 -07003528}
stefan658910c2015-09-03 05:48:32 -07003529
solenbergff976312016-03-30 23:28:51 -07003530// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003531TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3532 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3533 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3534 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003535 {
ossuc54071d2016-08-17 02:45:41 -07003536 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003537 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003538 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003539 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003540 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003541 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3542 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3543 EXPECT_TRUE(channel != nullptr);
3544 delete channel;
3545 }
stefan658910c2015-09-03 05:48:32 -07003546}
3547
3548// Tests that the library is configured with the codecs we want.
3549TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003550 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3551 // module.
3552
stefan658910c2015-09-03 05:48:32 -07003553 // Check codecs by name.
solenberg26c8c912015-11-27 04:00:25 -08003554 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003555 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003556 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003557 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003558 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003559 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003560 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003561 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003562 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003563 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003564 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003565 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003566 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003567 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003568 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003569 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003570 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003571 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3572 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3573 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3574 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3575 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3576 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003577 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003578 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003579 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003580 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003581 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003582 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003583 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003584 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003585 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003586 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003587 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003588 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003589 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003590 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003591 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003592 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003593 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003594 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003595 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003596 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003597 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003598 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003599 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003600
stefan658910c2015-09-03 05:48:32 -07003601 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003602 // TODO(ossu): Why are the payload types of codecs with non-static payload
3603 // type assignments checked here? It shouldn't really matter.
3604 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003605 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003606 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3607 if (codec.name == "CN" && codec.clockrate == 16000) {
3608 EXPECT_EQ(105, codec.id);
3609 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3610 EXPECT_EQ(106, codec.id);
3611 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3612 EXPECT_EQ(103, codec.id);
3613 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3614 EXPECT_EQ(104, codec.id);
3615 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3616 EXPECT_EQ(9, codec.id);
3617 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3618 EXPECT_EQ(126, codec.id);
3619 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3620 // Remove these checks once both send and receive side assigns payload types
3621 // dynamically.
3622 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3623 EXPECT_EQ(113, codec.id);
3624 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3625 EXPECT_EQ(112, codec.id);
3626 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3627 EXPECT_EQ(110, codec.id);
3628 } else if (codec.name == "opus") {
3629 EXPECT_EQ(111, codec.id);
3630 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3631 EXPECT_EQ("10", codec.params.find("minptime")->second);
3632 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3633 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003634 }
3635 }
stefan658910c2015-09-03 05:48:32 -07003636}
3637
3638// Tests that VoE supports at least 32 channels
3639TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003640 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003641 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003642 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003643 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003644 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003645
3646 cricket::VoiceMediaChannel* channels[32];
3647 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003648 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003649 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3650 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003651 if (!channel)
3652 break;
stefan658910c2015-09-03 05:48:32 -07003653 channels[num_channels++] = channel;
3654 }
3655
tfarina5237aaf2015-11-10 23:44:30 -08003656 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003657 EXPECT_EQ(expected, num_channels);
3658
3659 while (num_channels > 0) {
3660 delete channels[--num_channels];
3661 }
stefan658910c2015-09-03 05:48:32 -07003662}
3663
3664// Test that we set our preferred codecs properly.
3665TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003666 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3667 // - Check that our builtin codecs are usable by Channel.
3668 // - The codecs provided by the engine is usable by Channel.
3669 // It does not check that the codecs in the RecvParameters are actually
3670 // what we sent in - though it's probably reasonable to expect so, if
3671 // SetRecvParameters returns true.
3672 // I think it will become clear once audio decoder injection is completed.
3673 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003674 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003675 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003676 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003677 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003678 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3679 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003680 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003681 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003682 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003683}
ossu9def8002017-02-09 05:14:32 -08003684
3685TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3686 std::vector<webrtc::AudioCodecSpec> specs;
3687 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3688 spec1.allow_comfort_noise = false;
3689 spec1.supports_network_adaption = true;
3690 specs.push_back(spec1);
3691 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3692 spec2.allow_comfort_noise = false;
3693 specs.push_back(spec2);
3694 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3695 {{"param1", "value1b"},
3696 {"param2", "value2"}}}));
3697 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3698 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3699
3700 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3701 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3702 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3703 .WillOnce(Return(specs));
3704
3705 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3706 auto codecs = engine.recv_codecs();
3707 EXPECT_EQ(11, codecs.size());
3708
3709 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3710 // check the actual values safely, to provide better test results.
3711 auto get_codec =
3712 [&codecs](size_t index) -> const cricket::AudioCodec& {
3713 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3714 if (codecs.size() > index)
3715 return codecs[index];
3716 return missing_codec;
3717 };
3718
3719 // Ensure the general codecs are generated first and in order.
3720 for (size_t i = 0; i != specs.size(); ++i) {
3721 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3722 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3723 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3724 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3725 }
3726
3727 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003728 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003729 auto find_codec =
3730 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3731 for (size_t i = 0; i != codecs.size(); ++i) {
3732 const cricket::AudioCodec& codec = codecs[i];
3733 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3734 codec.clockrate == format.clockrate_hz &&
3735 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003736 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003737 }
3738 }
3739 return -1;
3740 };
3741
3742 // Ensure all supplementary codecs are generated last. Their internal ordering
3743 // is not important.
3744 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3745 const int num_specs = static_cast<int>(specs.size());
3746 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3747 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3748 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3749 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3750 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3751 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3752 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3753}