blob: c55389ae7361d9beaa4e8a1469a732019836e943 [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;
ossu11bfc532017-02-16 05:37:06 -08002571 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2572 constexpr int kMinOverheadBps =
2573 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002574 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2575
2576 constexpr int kOpusMinBitrateBps = 6000;
2577 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
2578 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2579 constexpr int kOpusBitrateFbBps = 32000;
2580 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
2581 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2582
2583 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2584 parameters.options.audio_network_adaptor_config =
2585 rtc::Optional<std::string>("1234");
2586 SetSendParameters(parameters);
2587
ossu11bfc532017-02-16 05:37:06 -08002588 constexpr int kMinOverheadWithAnaBps =
2589 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002590 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2591
2592 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
2593 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2594
2595 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
2596 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2597}
2598
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002599// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002600// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002601TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002602 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002603 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002604}
2605
2606TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2607 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002608 EXPECT_TRUE(SetupSendStream());
solenbergff976312016-03-30 23:28:51 -07002609 // SetupSendStream adds a send stream with kSsrc1, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002610 // stream has to use a different SSRC.
solenberg8189b022016-06-14 12:13:00 -07002611 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002612 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002613 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002614 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002615
solenberg85a04962015-10-27 03:35:21 -07002616 // Check stats for the added streams.
2617 {
2618 cricket::VoiceMediaInfo info;
2619 EXPECT_EQ(true, channel_->GetStats(&info));
2620
2621 // We have added one send stream. We should see the stats we've set.
2622 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002623 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002624 // We have added one receive stream. We should see empty stats.
2625 EXPECT_EQ(info.receivers.size(), 1u);
2626 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2627 }
solenberg1ac56142015-10-13 03:58:19 -07002628
solenberg566ef242015-11-06 15:34:49 -08002629 // Start sending - this affects some reported stats.
2630 {
2631 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002632 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002633 EXPECT_EQ(true, channel_->GetStats(&info));
2634 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002635 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002636 }
2637
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002638 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002639 {
2640 cricket::VoiceMediaInfo info;
2641 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2642 EXPECT_EQ(true, channel_->GetStats(&info));
2643 EXPECT_EQ(1u, info.senders.size());
2644 EXPECT_EQ(0u, info.receivers.size());
2645 }
solenberg1ac56142015-10-13 03:58:19 -07002646
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002647 // Deliver a new packet - a default receive stream should be created and we
2648 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002649 {
2650 cricket::VoiceMediaInfo info;
2651 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2652 SetAudioReceiveStreamStats();
2653 EXPECT_EQ(true, channel_->GetStats(&info));
2654 EXPECT_EQ(1u, info.senders.size());
2655 EXPECT_EQ(1u, info.receivers.size());
2656 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002657 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002658 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002659}
2660
2661// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002662// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002664 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002665 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg8189b022016-06-14 12:13:00 -07002666 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -08002667 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002668}
2669
2670// Test that the local SSRC is the same on sending and receiving channels if the
2671// receive channel is created before the send channel.
2672TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002673 EXPECT_TRUE(SetupChannel());
solenberg4a0f7b52016-06-16 13:07:33 -07002674 EXPECT_TRUE(AddRecvStream(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002675 EXPECT_TRUE(channel_->AddSendStream(
solenberg4a0f7b52016-06-16 13:07:33 -07002676 cricket::StreamParams::CreateLegacy(kSsrc1)));
2677 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2678 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002679}
2680
2681// Test that we can properly receive packets.
2682TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002683 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002684 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002686
2687 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2688 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002689}
2690
2691// Test that we can properly receive packets on multiple streams.
2692TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002693 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002694 const uint32_t ssrc1 = 1;
2695 const uint32_t ssrc2 = 2;
2696 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002697 EXPECT_TRUE(AddRecvStream(ssrc1));
2698 EXPECT_TRUE(AddRecvStream(ssrc2));
2699 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002701 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002702 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002704 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705 }
mflodman3d7db262016-04-29 00:57:13 -07002706
2707 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2708 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2709 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2710
2711 EXPECT_EQ(s1.received_packets(), 0);
2712 EXPECT_EQ(s2.received_packets(), 0);
2713 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002714
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002716 EXPECT_EQ(s1.received_packets(), 0);
2717 EXPECT_EQ(s2.received_packets(), 0);
2718 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002719
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002721 EXPECT_EQ(s1.received_packets(), 1);
2722 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2723 EXPECT_EQ(s2.received_packets(), 0);
2724 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002725
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002726 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002727 EXPECT_EQ(s1.received_packets(), 1);
2728 EXPECT_EQ(s2.received_packets(), 1);
2729 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2730 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002731
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002733 EXPECT_EQ(s1.received_packets(), 1);
2734 EXPECT_EQ(s2.received_packets(), 1);
2735 EXPECT_EQ(s3.received_packets(), 1);
2736 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002737
mflodman3d7db262016-04-29 00:57:13 -07002738 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2739 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2740 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002741}
2742
solenberg7e63ef02015-11-20 00:19:43 -08002743// Test that receiving on an unsignalled stream works (default channel will be
2744// created).
2745TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
solenbergff976312016-03-30 23:28:51 -07002746 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002747 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2748
solenberg7e63ef02015-11-20 00:19:43 -08002749 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002750
2751 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2752 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2753 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002754}
2755
2756// Test that receiving on an unsignalled stream works (default channel will be
2757// created), and that packets will be forwarded to the default channel
2758// regardless of their SSRCs.
2759TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
solenbergff976312016-03-30 23:28:51 -07002760 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002761 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002762 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2763
mflodman3d7db262016-04-29 00:57:13 -07002764 // Note that ssrc = 0 is not supported.
2765 uint32_t ssrc = 1;
2766 for (; ssrc < 10; ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002767 rtc::SetBE32(&packet[8], ssrc);
2768 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002769
2770 // Verify we only have one default stream.
2771 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2772 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2773 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002774 }
mflodman3d7db262016-04-29 00:57:13 -07002775
2776 // Sending the same ssrc again should not create a new stream.
2777 --ssrc;
2778 DeliverPacket(packet, sizeof(packet));
2779 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2780 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2781 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002782}
2783
2784// Test that a default channel is created even after a signalled stream has been
2785// added, and that this stream will get any packets for unknown SSRCs.
2786TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
solenbergff976312016-03-30 23:28:51 -07002787 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002788 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002789 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2790
2791 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002792 const uint32_t signaled_ssrc = 1;
2793 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002794 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002795 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002796 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2797 packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002798
2799 // Note that the first unknown SSRC cannot be 0, because we only support
2800 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002801 const uint32_t unsignaled_ssrc = 7011;
2802 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002803 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002804 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2805 packet, sizeof(packet)));
2806 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2807
2808 DeliverPacket(packet, sizeof(packet));
2809 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2810
2811 rtc::SetBE32(&packet[8], signaled_ssrc);
2812 DeliverPacket(packet, sizeof(packet));
2813 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2814 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002815}
2816
solenberg0a617e22015-10-20 15:49:38 -07002817// Test that we properly handle failures to add a receive stream.
2818TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002819 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002821 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822}
2823
solenberg0a617e22015-10-20 15:49:38 -07002824// Test that we properly handle failures to add a send stream.
2825TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002826 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002827 voe_.set_fail_create_channel(true);
2828 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2829}
2830
solenberg1ac56142015-10-13 03:58:19 -07002831// Test that AddRecvStream creates new stream.
2832TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002833 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002834 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002835 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002836 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837}
2838
2839// Test that after adding a recv stream, we do not decode more codecs than
2840// those previously passed into SetRecvCodecs.
2841TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002842 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002843 cricket::AudioRecvParameters parameters;
2844 parameters.codecs.push_back(kIsacCodec);
2845 parameters.codecs.push_back(kPcmuCodec);
2846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002847 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848 int channel_num2 = voe_.GetLastChannel();
2849 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002850 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002851 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852 gcodec.channels = 2;
2853 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2854}
2855
2856// Test that we properly clean up any streams that were added, even if
2857// not explicitly removed.
2858TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002859 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002860 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002861 EXPECT_TRUE(AddRecvStream(1));
2862 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2864 delete channel_;
2865 channel_ = NULL;
2866 EXPECT_EQ(0, voe_.GetNumChannels());
2867}
2868
wu@webrtc.org78187522013-10-07 23:32:02 +00002869TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002870 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002871 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002872}
2873
2874TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002875 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002876 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002877 // Manually delete channel to simulate a failure.
2878 int channel = voe_.GetLastChannel();
2879 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2880 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002881 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002882 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002883 EXPECT_NE(channel, new_channel);
2884 // The last created channel is deleted too.
2885 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002886}
2887
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002888// Test the InsertDtmf on default send stream as caller.
2889TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002890 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891}
2892
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002893// Test the InsertDtmf on default send stream as callee
2894TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002895 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002896}
2897
2898// Test the InsertDtmf on specified send stream as caller.
2899TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002900 TestInsertDtmf(kSsrc1, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002901}
2902
2903// Test the InsertDtmf on specified send stream as callee.
2904TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002905 TestInsertDtmf(kSsrc1, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906}
2907
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002909 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002910 EXPECT_CALL(adm_,
2911 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2912 EXPECT_CALL(adm_,
2913 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2914 EXPECT_CALL(adm_,
2915 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002916 bool ec_enabled;
2917 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918 webrtc::AecmModes aecm_mode;
2919 bool cng_enabled;
2920 bool agc_enabled;
2921 webrtc::AgcModes agc_mode;
2922 webrtc::AgcConfig agc_config;
2923 bool ns_enabled;
2924 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925 bool stereo_swapping_enabled;
2926 bool typing_detection_enabled;
2927 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928 voe_.GetAecmMode(aecm_mode, cng_enabled);
2929 voe_.GetAgcStatus(agc_enabled, agc_mode);
2930 voe_.GetAgcConfig(agc_config);
2931 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2933 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2934 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002935 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936 EXPECT_FALSE(cng_enabled);
2937 EXPECT_TRUE(agc_enabled);
2938 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2939 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002940 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002941 EXPECT_FALSE(stereo_swapping_enabled);
2942 EXPECT_TRUE(typing_detection_enabled);
2943 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2944 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002945 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2946 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947
solenberg246b8172015-12-08 09:50:23 -08002948 // Nothing set in AudioOptions, so everything should be as default.
2949 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002950 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002951 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 voe_.GetAecmMode(aecm_mode, cng_enabled);
2953 voe_.GetAgcStatus(agc_enabled, agc_mode);
2954 voe_.GetAgcConfig(agc_config);
2955 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2957 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2958 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002959 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002960 EXPECT_FALSE(cng_enabled);
2961 EXPECT_TRUE(agc_enabled);
2962 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2963 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002964 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002965 EXPECT_FALSE(stereo_swapping_enabled);
2966 EXPECT_TRUE(typing_detection_enabled);
2967 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2968 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002969 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2970 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971
2972 // Turn echo cancellation off
solenberg246b8172015-12-08 09:50:23 -08002973 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002974 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975 voe_.GetEcStatus(ec_enabled, ec_mode);
2976 EXPECT_FALSE(ec_enabled);
2977
2978 // Turn echo cancellation back on, with settings, and make sure
2979 // nothing else changed.
solenberg246b8172015-12-08 09:50:23 -08002980 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002981 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002982 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983 voe_.GetAecmMode(aecm_mode, cng_enabled);
2984 voe_.GetAgcStatus(agc_enabled, agc_mode);
2985 voe_.GetAgcConfig(agc_config);
2986 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2988 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2989 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002990 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 EXPECT_TRUE(agc_enabled);
2992 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2993 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002994 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995 EXPECT_FALSE(stereo_swapping_enabled);
2996 EXPECT_TRUE(typing_detection_enabled);
2997 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2998 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2999
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003000 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3001 // control.
solenberg246b8172015-12-08 09:50:23 -08003002 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003003 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003004 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003005 voe_.GetAecmMode(aecm_mode, cng_enabled);
3006 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003007 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003008 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3009
3010 // Turn off echo cancellation and delay agnostic aec.
solenberg246b8172015-12-08 09:50:23 -08003011 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3012 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3013 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003014 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003015 voe_.GetEcStatus(ec_enabled, ec_mode);
3016 EXPECT_FALSE(ec_enabled);
3017 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg246b8172015-12-08 09:50:23 -08003018 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003019 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003020 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003021 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003022 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003023 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3024
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025 // Turn off AGC
solenberg246b8172015-12-08 09:50:23 -08003026 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003027 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028 voe_.GetAgcStatus(agc_enabled, agc_mode);
3029 EXPECT_FALSE(agc_enabled);
3030
3031 // Turn AGC back on
solenberg246b8172015-12-08 09:50:23 -08003032 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3033 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003034 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035 voe_.GetAgcStatus(agc_enabled, agc_mode);
3036 EXPECT_TRUE(agc_enabled);
3037 voe_.GetAgcConfig(agc_config);
3038 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3039
3040 // Turn off other options (and stereo swapping on).
solenberg246b8172015-12-08 09:50:23 -08003041 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3042 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3043 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3044 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003045 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3048 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3049 EXPECT_FALSE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003050 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003051 EXPECT_FALSE(typing_detection_enabled);
3052 EXPECT_TRUE(stereo_swapping_enabled);
3053
solenberg1ac56142015-10-13 03:58:19 -07003054 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07003055 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003056 voe_.GetEcStatus(ec_enabled, ec_mode);
3057 voe_.GetNsStatus(ns_enabled, ns_mode);
3058 EXPECT_TRUE(ec_enabled);
3059 EXPECT_EQ(webrtc::kEcConference, ec_mode);
3060 EXPECT_FALSE(ns_enabled);
3061 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
3062}
3063
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003064TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
solenbergff976312016-03-30 23:28:51 -07003065 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066
3067 bool ec_enabled;
3068 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069 bool agc_enabled;
3070 webrtc::AgcModes agc_mode;
3071 bool ns_enabled;
3072 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003073 bool stereo_swapping_enabled;
3074 bool typing_detection_enabled;
3075
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003076 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077 voe_.GetAgcStatus(agc_enabled, agc_mode);
3078 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003079 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3080 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3081 EXPECT_TRUE(ec_enabled);
3082 EXPECT_TRUE(agc_enabled);
3083 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003084 EXPECT_TRUE(IsHighPassFilterEnabled());
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003085 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003086 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003087}
3088
3089TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3090 webrtc::AgcConfig set_config = {0};
3091 set_config.targetLeveldBOv = 3;
3092 set_config.digitalCompressionGaindB = 9;
3093 set_config.limiterEnable = true;
3094 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003095
3096 webrtc::AgcConfig config = {0};
3097 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3098 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3099 EXPECT_EQ(set_config.digitalCompressionGaindB,
3100 config.digitalCompressionGaindB);
3101 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3102}
3103
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003104TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003105 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003106 EXPECT_CALL(adm_,
3107 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3108 EXPECT_CALL(adm_,
3109 BuiltInAGCIsAvailable()).Times(9).WillRepeatedly(Return(false));
3110 EXPECT_CALL(adm_,
3111 BuiltInNSIsAvailable()).Times(9).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003112 EXPECT_CALL(adm_,
3113 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3114 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3115 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3116 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3117 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003118
kwiberg686a8ef2016-02-26 03:00:35 -08003119 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
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())));
kwiberg686a8ef2016-02-26 03:00:35 -08003122 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003123 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003124 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003125
3126 // Have to add a stream to make SetSend work.
3127 cricket::StreamParams stream1;
3128 stream1.ssrcs.push_back(1);
3129 channel1->AddSendStream(stream1);
3130 cricket::StreamParams stream2;
3131 stream2.ssrcs.push_back(2);
3132 channel2->AddSendStream(stream2);
3133
3134 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003135 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003136 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3137 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3138 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003139 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003140 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003141 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003142 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003143
3144 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003145 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003146 parameters_options_no_ns.options.noise_suppression =
3147 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003148 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003149 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003150 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3151 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3152 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003153 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003154
3155 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003156 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003157 parameters_options_no_agc.options.auto_gain_control =
3158 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003159 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003160 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3161 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3162 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003163 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003164
solenberg059fb442016-10-26 05:12:24 -07003165 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003166 bool ec_enabled;
3167 webrtc::EcModes ec_mode;
3168 bool agc_enabled;
3169 webrtc::AgcModes agc_mode;
3170 bool ns_enabled;
3171 webrtc::NsModes ns_mode;
3172 voe_.GetEcStatus(ec_enabled, ec_mode);
3173 voe_.GetAgcStatus(agc_enabled, agc_mode);
3174 voe_.GetNsStatus(ns_enabled, ns_mode);
3175 EXPECT_TRUE(ec_enabled);
3176 EXPECT_TRUE(agc_enabled);
3177 EXPECT_TRUE(ns_enabled);
3178
solenberg059fb442016-10-26 05:12:24 -07003179 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003180 voe_.GetEcStatus(ec_enabled, ec_mode);
3181 voe_.GetAgcStatus(agc_enabled, agc_mode);
3182 voe_.GetNsStatus(ns_enabled, ns_mode);
3183 EXPECT_TRUE(ec_enabled);
3184 EXPECT_TRUE(agc_enabled);
3185 EXPECT_FALSE(ns_enabled);
3186
solenberg059fb442016-10-26 05:12:24 -07003187 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003188 voe_.GetEcStatus(ec_enabled, ec_mode);
3189 voe_.GetAgcStatus(agc_enabled, agc_mode);
3190 voe_.GetNsStatus(ns_enabled, ns_mode);
3191 EXPECT_TRUE(ec_enabled);
3192 EXPECT_FALSE(agc_enabled);
3193 EXPECT_TRUE(ns_enabled);
3194
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003195 // Make sure settings take effect while we are sending.
solenberg059fb442016-10-26 05:12:24 -07003196 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
3197 EXPECT_CALL(apm_, ApplyConfig(testing::_));
3198 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003199 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3200 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003201 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003202 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003203 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003204 rtc::Optional<bool>(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08003205 channel2->SetSend(true);
solenberg059fb442016-10-26 05:12:24 -07003206 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003207 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3208 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3209 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003210 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003211 voe_.GetEcStatus(ec_enabled, ec_mode);
3212 voe_.GetAgcStatus(agc_enabled, agc_mode);
3213 voe_.GetNsStatus(ns_enabled, ns_mode);
3214 EXPECT_TRUE(ec_enabled);
3215 EXPECT_FALSE(agc_enabled);
3216 EXPECT_FALSE(ns_enabled);
3217}
3218
wu@webrtc.orgde305012013-10-31 15:40:38 +00003219// This test verifies DSCP settings are properly applied on voice media channel.
3220TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003221 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003222 cricket::FakeNetworkInterface network_interface;
3223 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003224 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003225
solenberg059fb442016-10-26 05:12:24 -07003226 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3227 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3228
solenbergbc37fc82016-04-04 09:54:44 -07003229 channel.reset(
3230 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003231 channel->SetInterface(&network_interface);
3232 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3233 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3234
3235 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003236 channel.reset(
3237 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003238 channel->SetInterface(&network_interface);
3239 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3240
3241 // Verify that setting the option to false resets the
3242 // DiffServCodePoint.
3243 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003244 channel.reset(
3245 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003246 channel->SetInterface(&network_interface);
3247 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3248 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3249
3250 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003251}
3252
solenberg1ac56142015-10-13 03:58:19 -07003253TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003254 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255 cricket::WebRtcVoiceMediaChannel* media_channel =
3256 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003257 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003258 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003259 int channel_id = voe_.GetLastChannel();
3260 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3261 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003262 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003263 int channel_id2 = voe_.GetLastChannel();
3264 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003265}
3266
solenberg1ac56142015-10-13 03:58:19 -07003267TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003268 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003269 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003270 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3271 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3272 EXPECT_TRUE(channel_->AddSendStream(
3273 cricket::StreamParams::CreateLegacy(kSsrc1)));
3274 int channel_id = voe_.GetLastChannel();
3275 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3276 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3277 EXPECT_TRUE(channel_->AddSendStream(
3278 cricket::StreamParams::CreateLegacy(kSsrc2)));
3279 int channel_id2 = voe_.GetLastChannel();
3280 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003281}
3282
solenberg4bac9c52015-10-09 02:32:53 -07003283TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003284 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003285 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003286 cricket::StreamParams stream;
3287 stream.ssrcs.push_back(kSsrc2);
3288 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003289 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003290 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003291 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003292}
3293
3294TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003295 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003296 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3297 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003298 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003299 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003300 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3301 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3302 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003303}
3304
pbos8fc7fa72015-07-15 08:02:58 -07003305TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003306 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003307 const std::string kSyncLabel = "AvSyncLabel";
3308
solenbergff976312016-03-30 23:28:51 -07003309 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003310 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3311 sp.sync_label = kSyncLabel;
3312 // Creating two channels to make sure that sync label is set properly for both
3313 // the default voice channel and following ones.
3314 EXPECT_TRUE(channel_->AddRecvStream(sp));
3315 sp.ssrcs[0] += 1;
3316 EXPECT_TRUE(channel_->AddRecvStream(sp));
3317
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003318 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003319 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003320 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003321 << "SyncGroup should be set based on sync_label";
3322 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003323 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003324 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003325}
3326
solenberg3a941542015-11-16 07:34:50 -08003327// TODO(solenberg): Remove, once recv streams are configured through Call.
3328// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003329TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003330 // Test that setting the header extensions results in the expected state
3331 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003332 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003333 ssrcs.push_back(223);
3334 ssrcs.push_back(224);
3335
solenbergff976312016-03-30 23:28:51 -07003336 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003337 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003338 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003339 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003340 cricket::StreamParams::CreateLegacy(ssrc)));
3341 }
3342
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003343 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003344 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003345 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003346 EXPECT_NE(nullptr, s);
3347 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3348 }
3349
3350 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003351 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003352 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003353 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003354 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003355 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003356 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003357 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003358 EXPECT_NE(nullptr, s);
3359 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003360 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3361 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003362 for (const auto& s_ext : s_exts) {
3363 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003364 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003365 }
3366 }
3367 }
3368 }
3369
3370 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003371 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003372 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003373 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374 EXPECT_NE(nullptr, s);
3375 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3376 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003377}
3378
3379TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3380 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003381 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003382 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003383 static const unsigned char kRtcp[] = {
3384 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3385 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3388 };
jbaucheec21bd2016-03-20 06:15:43 -07003389 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003390
solenbergff976312016-03-30 23:28:51 -07003391 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003392 cricket::WebRtcVoiceMediaChannel* media_channel =
3393 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003394 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003395 EXPECT_TRUE(media_channel->AddRecvStream(
3396 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3397
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003398 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003399 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003400 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003401 EXPECT_EQ(0, s->received_packets());
3402 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3403 EXPECT_EQ(1, s->received_packets());
3404 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3405 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003406}
Minyue2013aec2015-05-13 14:14:42 +02003407
solenberg0a617e22015-10-20 15:49:38 -07003408// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003409// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003410TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003411 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003412 EXPECT_TRUE(AddRecvStream(kSsrc2));
3413 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3414 EXPECT_TRUE(channel_->AddSendStream(
3415 cricket::StreamParams::CreateLegacy(kSsrc3)));
3416 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3417 EXPECT_TRUE(AddRecvStream(kSsrc4));
3418 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003419}
3420
solenberg7602aab2016-11-14 11:30:07 -08003421TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3422 EXPECT_TRUE(SetupRecvStream());
3423 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3424 EXPECT_TRUE(channel_->AddSendStream(
3425 cricket::StreamParams::CreateLegacy(kSsrc2)));
3426 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3427 EXPECT_TRUE(AddRecvStream(kSsrc3));
3428 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3429 EXPECT_TRUE(channel_->AddSendStream(
3430 cricket::StreamParams::CreateLegacy(kSsrc4)));
3431 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3432 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003433}
stefan658910c2015-09-03 05:48:32 -07003434
deadbeef884f5852016-01-15 09:20:04 -08003435TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003436 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003437 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3438 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003439
3440 // Setting the sink before a recv stream exists should do nothing.
3441 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003442 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003443 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3444
3445 // Now try actually setting the sink.
3446 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3447 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3448
3449 // Now try resetting it.
3450 channel_->SetRawAudioSink(kSsrc1, nullptr);
3451 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3452}
3453
3454TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003455 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003456 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3457 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003458
3459 // Should be able to set a default sink even when no stream exists.
3460 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3461
3462 // Create default channel and ensure it's assigned the default sink.
3463 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3464 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3465
3466 // Try resetting the default sink.
3467 channel_->SetRawAudioSink(0, nullptr);
3468 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3469
3470 // Try setting the default sink while the default stream exists.
3471 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3472 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3473
3474 // If we remove and add a default stream, it should get the same sink.
3475 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3476 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3477 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3478}
3479
skvlad7a43d252016-03-22 15:32:27 -07003480// Test that, just like the video channel, the voice channel communicates the
3481// network state to the call.
3482TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003483 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003484
3485 EXPECT_EQ(webrtc::kNetworkUp,
3486 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3487 EXPECT_EQ(webrtc::kNetworkUp,
3488 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3489
3490 channel_->OnReadyToSend(false);
3491 EXPECT_EQ(webrtc::kNetworkDown,
3492 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3493 EXPECT_EQ(webrtc::kNetworkUp,
3494 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3495
3496 channel_->OnReadyToSend(true);
3497 EXPECT_EQ(webrtc::kNetworkUp,
3498 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3499 EXPECT_EQ(webrtc::kNetworkUp,
3500 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3501}
3502
aleloi18e0b672016-10-04 02:45:47 -07003503// Test that playout is still started after changing parameters
3504TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3505 SetupRecvStream();
3506 channel_->SetPlayout(true);
3507 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3508
3509 // Changing RTP header extensions will recreate the AudioReceiveStream.
3510 cricket::AudioRecvParameters parameters;
3511 parameters.extensions.push_back(
3512 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3513 channel_->SetRecvParameters(parameters);
3514
3515 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3516}
3517
stefan658910c2015-09-03 05:48:32 -07003518// Tests that the library initializes and shuts down properly.
3519TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003520 // If the VoiceEngine wants to gather available codecs early, that's fine but
3521 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003522 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003523 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003524 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003525 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003526 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003527 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3528 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003529 EXPECT_TRUE(channel != nullptr);
3530 delete channel;
solenbergff976312016-03-30 23:28:51 -07003531}
stefan658910c2015-09-03 05:48:32 -07003532
solenbergff976312016-03-30 23:28:51 -07003533// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003534TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3535 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3536 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3537 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003538 {
ossuc54071d2016-08-17 02:45:41 -07003539 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003540 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003541 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003542 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003543 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003544 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3545 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3546 EXPECT_TRUE(channel != nullptr);
3547 delete channel;
3548 }
stefan658910c2015-09-03 05:48:32 -07003549}
3550
3551// Tests that the library is configured with the codecs we want.
3552TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003553 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3554 // module.
3555
stefan658910c2015-09-03 05:48:32 -07003556 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003557#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003558 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003559 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003560#endif
3561#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003562 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003563 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003564#endif
3565#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003566 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003567 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003568#endif
3569#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003570 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003571 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003572 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003573 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003574 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003575#endif
solenberg26c8c912015-11-27 04:00:25 -08003576 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003577 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003578 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003579 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003580 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003581 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003582 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3583 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3584 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3585 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3586 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3587 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003588 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003589 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003590 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003591 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003592 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003593 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003594 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003595 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003596 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003597 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003598 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003599 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003600 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003601 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003602 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003603 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003604 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003605 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003606 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003607 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003608 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003609 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003610 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003611
stefan658910c2015-09-03 05:48:32 -07003612 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003613 // TODO(ossu): Why are the payload types of codecs with non-static payload
3614 // type assignments checked here? It shouldn't really matter.
3615 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003616 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003617 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3618 if (codec.name == "CN" && codec.clockrate == 16000) {
3619 EXPECT_EQ(105, codec.id);
3620 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3621 EXPECT_EQ(106, codec.id);
3622 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3623 EXPECT_EQ(103, codec.id);
3624 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3625 EXPECT_EQ(104, codec.id);
3626 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3627 EXPECT_EQ(9, codec.id);
3628 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3629 EXPECT_EQ(126, codec.id);
3630 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3631 // Remove these checks once both send and receive side assigns payload types
3632 // dynamically.
3633 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3634 EXPECT_EQ(113, codec.id);
3635 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3636 EXPECT_EQ(112, codec.id);
3637 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3638 EXPECT_EQ(110, codec.id);
3639 } else if (codec.name == "opus") {
3640 EXPECT_EQ(111, codec.id);
3641 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3642 EXPECT_EQ("10", codec.params.find("minptime")->second);
3643 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3644 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003645 }
3646 }
stefan658910c2015-09-03 05:48:32 -07003647}
3648
3649// Tests that VoE supports at least 32 channels
3650TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003651 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003652 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003653 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003654 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003655 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003656
3657 cricket::VoiceMediaChannel* channels[32];
3658 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003659 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003660 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3661 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003662 if (!channel)
3663 break;
stefan658910c2015-09-03 05:48:32 -07003664 channels[num_channels++] = channel;
3665 }
3666
tfarina5237aaf2015-11-10 23:44:30 -08003667 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003668 EXPECT_EQ(expected, num_channels);
3669
3670 while (num_channels > 0) {
3671 delete channels[--num_channels];
3672 }
stefan658910c2015-09-03 05:48:32 -07003673}
3674
3675// Test that we set our preferred codecs properly.
3676TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003677 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3678 // - Check that our builtin codecs are usable by Channel.
3679 // - The codecs provided by the engine is usable by Channel.
3680 // It does not check that the codecs in the RecvParameters are actually
3681 // what we sent in - though it's probably reasonable to expect so, if
3682 // SetRecvParameters returns true.
3683 // I think it will become clear once audio decoder injection is completed.
3684 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003685 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003686 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003687 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003688 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003689 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3690 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003691 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003692 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003693 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003694}
ossu9def8002017-02-09 05:14:32 -08003695
3696TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3697 std::vector<webrtc::AudioCodecSpec> specs;
3698 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3699 spec1.allow_comfort_noise = false;
3700 spec1.supports_network_adaption = true;
3701 specs.push_back(spec1);
3702 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3703 spec2.allow_comfort_noise = false;
3704 specs.push_back(spec2);
3705 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3706 {{"param1", "value1b"},
3707 {"param2", "value2"}}}));
3708 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3709 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3710
3711 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3712 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3713 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3714 .WillOnce(Return(specs));
3715
3716 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3717 auto codecs = engine.recv_codecs();
3718 EXPECT_EQ(11, codecs.size());
3719
3720 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3721 // check the actual values safely, to provide better test results.
3722 auto get_codec =
3723 [&codecs](size_t index) -> const cricket::AudioCodec& {
3724 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3725 if (codecs.size() > index)
3726 return codecs[index];
3727 return missing_codec;
3728 };
3729
3730 // Ensure the general codecs are generated first and in order.
3731 for (size_t i = 0; i != specs.size(); ++i) {
3732 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3733 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3734 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3735 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3736 }
3737
3738 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003739 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003740 auto find_codec =
3741 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3742 for (size_t i = 0; i != codecs.size(); ++i) {
3743 const cricket::AudioCodec& codec = codecs[i];
3744 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3745 codec.clockrate == format.clockrate_hz &&
3746 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003747 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003748 }
3749 }
3750 return -1;
3751 };
3752
3753 // Ensure all supplementary codecs are generated last. Their internal ordering
3754 // is not important.
3755 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3756 const int num_specs = static_cast<int>(specs.size());
3757 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3758 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3759 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3760 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3761 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3762 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3763 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3764}