blob: 0bb350133933a0fc477b0644b620337535999990 [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
solenberg4904fb62017-02-17 12:01:14 -08002817// Two tests to verify that adding a receive stream with the same SSRC as a
2818// previously added unsignaled stream will only recreate underlying stream
2819// objects if the stream parameters have changed.
2820TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2821 EXPECT_TRUE(SetupChannel());
2822
2823 // Spawn unsignaled stream with SSRC=1.
2824 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2825 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2826 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2827 sizeof(kPcmuFrame)));
2828
2829 // Verify that the underlying stream object in Call is not recreated when a
2830 // stream with SSRC=1 is added.
2831 const auto& streams = call_.GetAudioReceiveStreams();
2832 EXPECT_EQ(1, streams.size());
2833 int audio_receive_stream_id = streams.front()->id();
2834 EXPECT_TRUE(AddRecvStream(1));
2835 EXPECT_EQ(1, streams.size());
2836 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2837}
2838
2839TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2840 EXPECT_TRUE(SetupChannel());
2841
2842 // Spawn unsignaled stream with SSRC=1.
2843 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2844 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2845 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2846 sizeof(kPcmuFrame)));
2847
2848 // Verify that the underlying stream object in Call *is* recreated when a
2849 // stream with SSRC=1 is added, and which has changed stream parameters.
2850 const auto& streams = call_.GetAudioReceiveStreams();
2851 EXPECT_EQ(1, streams.size());
2852 int audio_receive_stream_id = streams.front()->id();
2853 cricket::StreamParams stream_params;
2854 stream_params.ssrcs.push_back(1);
2855 stream_params.sync_label = "sync_label";
2856 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2857 EXPECT_EQ(1, streams.size());
2858 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2859}
2860
solenberg0a617e22015-10-20 15:49:38 -07002861// Test that we properly handle failures to add a receive stream.
2862TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002863 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002865 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866}
2867
solenberg0a617e22015-10-20 15:49:38 -07002868// Test that we properly handle failures to add a send stream.
2869TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002870 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002871 voe_.set_fail_create_channel(true);
2872 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2873}
2874
solenberg1ac56142015-10-13 03:58:19 -07002875// Test that AddRecvStream creates new stream.
2876TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002877 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002879 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002880 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881}
2882
2883// Test that after adding a recv stream, we do not decode more codecs than
2884// those previously passed into SetRecvCodecs.
2885TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002886 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002887 cricket::AudioRecvParameters parameters;
2888 parameters.codecs.push_back(kIsacCodec);
2889 parameters.codecs.push_back(kPcmuCodec);
2890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002891 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892 int channel_num2 = voe_.GetLastChannel();
2893 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002894 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002895 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896 gcodec.channels = 2;
2897 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2898}
2899
2900// Test that we properly clean up any streams that were added, even if
2901// not explicitly removed.
2902TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002903 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002904 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002905 EXPECT_TRUE(AddRecvStream(1));
2906 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2908 delete channel_;
2909 channel_ = NULL;
2910 EXPECT_EQ(0, voe_.GetNumChannels());
2911}
2912
wu@webrtc.org78187522013-10-07 23:32:02 +00002913TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002914 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002915 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002916}
2917
2918TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002919 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002920 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002921 // Manually delete channel to simulate a failure.
2922 int channel = voe_.GetLastChannel();
2923 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2924 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002925 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002926 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002927 EXPECT_NE(channel, new_channel);
2928 // The last created channel is deleted too.
2929 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002930}
2931
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002932// Test the InsertDtmf on default send stream as caller.
2933TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002934 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935}
2936
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002937// Test the InsertDtmf on default send stream as callee
2938TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002939 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002940}
2941
2942// Test the InsertDtmf on specified send stream as caller.
2943TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002944 TestInsertDtmf(kSsrc1, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002945}
2946
2947// Test the InsertDtmf on specified send stream as callee.
2948TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002949 TestInsertDtmf(kSsrc1, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002950}
2951
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002953 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002954 EXPECT_CALL(adm_,
2955 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2956 EXPECT_CALL(adm_,
2957 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2958 EXPECT_CALL(adm_,
2959 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002960 bool ec_enabled;
2961 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962 webrtc::AecmModes aecm_mode;
2963 bool cng_enabled;
2964 bool agc_enabled;
2965 webrtc::AgcModes agc_mode;
2966 webrtc::AgcConfig agc_config;
2967 bool ns_enabled;
2968 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002969 bool stereo_swapping_enabled;
2970 bool typing_detection_enabled;
2971 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 voe_.GetAecmMode(aecm_mode, cng_enabled);
2973 voe_.GetAgcStatus(agc_enabled, agc_mode);
2974 voe_.GetAgcConfig(agc_config);
2975 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002976 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2977 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2978 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07002979 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980 EXPECT_FALSE(cng_enabled);
2981 EXPECT_TRUE(agc_enabled);
2982 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2983 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08002984 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985 EXPECT_FALSE(stereo_swapping_enabled);
2986 EXPECT_TRUE(typing_detection_enabled);
2987 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2988 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08002989 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2990 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991
solenberg246b8172015-12-08 09:50:23 -08002992 // Nothing set in AudioOptions, so everything should be as default.
2993 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002994 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996 voe_.GetAecmMode(aecm_mode, cng_enabled);
2997 voe_.GetAgcStatus(agc_enabled, agc_mode);
2998 voe_.GetAgcConfig(agc_config);
2999 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3001 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3002 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003003 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004 EXPECT_FALSE(cng_enabled);
3005 EXPECT_TRUE(agc_enabled);
3006 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3007 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003008 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003009 EXPECT_FALSE(stereo_swapping_enabled);
3010 EXPECT_TRUE(typing_detection_enabled);
3011 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3012 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
solenberg246b8172015-12-08 09:50:23 -08003013 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3014 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015
3016 // Turn echo cancellation off
solenberg246b8172015-12-08 09:50:23 -08003017 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003018 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019 voe_.GetEcStatus(ec_enabled, ec_mode);
3020 EXPECT_FALSE(ec_enabled);
3021
3022 // Turn echo cancellation back on, with settings, and make sure
3023 // nothing else changed.
solenberg246b8172015-12-08 09:50:23 -08003024 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003025 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003026 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027 voe_.GetAecmMode(aecm_mode, cng_enabled);
3028 voe_.GetAgcStatus(agc_enabled, agc_mode);
3029 voe_.GetAgcConfig(agc_config);
3030 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3032 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3033 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003034 EXPECT_TRUE(voe_.ec_metrics_enabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035 EXPECT_TRUE(agc_enabled);
3036 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3037 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003038 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003039 EXPECT_FALSE(stereo_swapping_enabled);
3040 EXPECT_TRUE(typing_detection_enabled);
3041 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3042 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
3043
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003044 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3045 // control.
solenberg246b8172015-12-08 09:50:23 -08003046 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003047 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003048 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003049 voe_.GetAecmMode(aecm_mode, cng_enabled);
3050 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003051 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003052 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3053
3054 // Turn off echo cancellation and delay agnostic aec.
solenberg246b8172015-12-08 09:50:23 -08003055 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3056 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3057 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003058 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003059 voe_.GetEcStatus(ec_enabled, ec_mode);
3060 EXPECT_FALSE(ec_enabled);
3061 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg246b8172015-12-08 09:50:23 -08003062 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003063 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003064 voe_.GetEcStatus(ec_enabled, ec_mode);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003065 EXPECT_TRUE(ec_enabled);
solenberg85a04962015-10-27 03:35:21 -07003066 EXPECT_TRUE(voe_.ec_metrics_enabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003067 EXPECT_EQ(ec_mode, webrtc::kEcConference);
3068
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069 // Turn off AGC
solenberg246b8172015-12-08 09:50:23 -08003070 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003071 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003072 voe_.GetAgcStatus(agc_enabled, agc_mode);
3073 EXPECT_FALSE(agc_enabled);
3074
3075 // Turn AGC back on
solenberg246b8172015-12-08 09:50:23 -08003076 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3077 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003078 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003079 voe_.GetAgcStatus(agc_enabled, agc_mode);
3080 EXPECT_TRUE(agc_enabled);
3081 voe_.GetAgcConfig(agc_config);
3082 EXPECT_EQ(0, agc_config.targetLeveldBOv);
3083
3084 // Turn off other options (and stereo swapping on).
solenberg246b8172015-12-08 09:50:23 -08003085 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3086 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3087 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3088 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003089 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003090 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003091 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3092 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3093 EXPECT_FALSE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003094 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003095 EXPECT_FALSE(typing_detection_enabled);
3096 EXPECT_TRUE(stereo_swapping_enabled);
3097
solenberg1ac56142015-10-13 03:58:19 -07003098 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07003099 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003100 voe_.GetEcStatus(ec_enabled, ec_mode);
3101 voe_.GetNsStatus(ns_enabled, ns_mode);
3102 EXPECT_TRUE(ec_enabled);
3103 EXPECT_EQ(webrtc::kEcConference, ec_mode);
3104 EXPECT_FALSE(ns_enabled);
3105 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
3106}
3107
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003108TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
solenbergff976312016-03-30 23:28:51 -07003109 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003110
3111 bool ec_enabled;
3112 webrtc::EcModes ec_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003113 bool agc_enabled;
3114 webrtc::AgcModes agc_mode;
3115 bool ns_enabled;
3116 webrtc::NsModes ns_mode;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003117 bool stereo_swapping_enabled;
3118 bool typing_detection_enabled;
3119
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003120 voe_.GetEcStatus(ec_enabled, ec_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003121 voe_.GetAgcStatus(agc_enabled, agc_mode);
3122 voe_.GetNsStatus(ns_enabled, ns_mode);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003123 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3124 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3125 EXPECT_TRUE(ec_enabled);
3126 EXPECT_TRUE(agc_enabled);
3127 EXPECT_TRUE(ns_enabled);
peah8271d042016-11-22 07:24:52 -08003128 EXPECT_TRUE(IsHighPassFilterEnabled());
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003129 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003130 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003131}
3132
3133TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3134 webrtc::AgcConfig set_config = {0};
3135 set_config.targetLeveldBOv = 3;
3136 set_config.digitalCompressionGaindB = 9;
3137 set_config.limiterEnable = true;
3138 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003139
3140 webrtc::AgcConfig config = {0};
3141 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3142 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3143 EXPECT_EQ(set_config.digitalCompressionGaindB,
3144 config.digitalCompressionGaindB);
3145 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3146}
3147
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003149 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003150 EXPECT_CALL(adm_,
3151 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3152 EXPECT_CALL(adm_,
3153 BuiltInAGCIsAvailable()).Times(9).WillRepeatedly(Return(false));
3154 EXPECT_CALL(adm_,
3155 BuiltInNSIsAvailable()).Times(9).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003156 EXPECT_CALL(adm_,
3157 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3158 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3159 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3160 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3161 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003162
kwiberg686a8ef2016-02-26 03:00:35 -08003163 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003164 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003165 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003166 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003167 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003168 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003169
3170 // Have to add a stream to make SetSend work.
3171 cricket::StreamParams stream1;
3172 stream1.ssrcs.push_back(1);
3173 channel1->AddSendStream(stream1);
3174 cricket::StreamParams stream2;
3175 stream2.ssrcs.push_back(2);
3176 channel2->AddSendStream(stream2);
3177
3178 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003179 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003180 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3181 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3182 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003183 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003184 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003185 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003186 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003187
3188 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003189 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003190 parameters_options_no_ns.options.noise_suppression =
3191 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003192 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003193 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003194 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3195 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3196 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003197 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003198
3199 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003200 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003201 parameters_options_no_agc.options.auto_gain_control =
3202 rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003203 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003204 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3205 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3206 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003207 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003208
solenberg059fb442016-10-26 05:12:24 -07003209 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003210 bool ec_enabled;
3211 webrtc::EcModes ec_mode;
3212 bool agc_enabled;
3213 webrtc::AgcModes agc_mode;
3214 bool ns_enabled;
3215 webrtc::NsModes ns_mode;
3216 voe_.GetEcStatus(ec_enabled, ec_mode);
3217 voe_.GetAgcStatus(agc_enabled, agc_mode);
3218 voe_.GetNsStatus(ns_enabled, ns_mode);
3219 EXPECT_TRUE(ec_enabled);
3220 EXPECT_TRUE(agc_enabled);
3221 EXPECT_TRUE(ns_enabled);
3222
solenberg059fb442016-10-26 05:12:24 -07003223 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003224 voe_.GetEcStatus(ec_enabled, ec_mode);
3225 voe_.GetAgcStatus(agc_enabled, agc_mode);
3226 voe_.GetNsStatus(ns_enabled, ns_mode);
3227 EXPECT_TRUE(ec_enabled);
3228 EXPECT_TRUE(agc_enabled);
3229 EXPECT_FALSE(ns_enabled);
3230
solenberg059fb442016-10-26 05:12:24 -07003231 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003232 voe_.GetEcStatus(ec_enabled, ec_mode);
3233 voe_.GetAgcStatus(agc_enabled, agc_mode);
3234 voe_.GetNsStatus(ns_enabled, ns_mode);
3235 EXPECT_TRUE(ec_enabled);
3236 EXPECT_FALSE(agc_enabled);
3237 EXPECT_TRUE(ns_enabled);
3238
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003239 // Make sure settings take effect while we are sending.
solenberg059fb442016-10-26 05:12:24 -07003240 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
3241 EXPECT_CALL(apm_, ApplyConfig(testing::_));
3242 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003243 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3244 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003245 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003246 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003247 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003248 rtc::Optional<bool>(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08003249 channel2->SetSend(true);
solenberg059fb442016-10-26 05:12:24 -07003250 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003251 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3252 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3253 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003254 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255 voe_.GetEcStatus(ec_enabled, ec_mode);
3256 voe_.GetAgcStatus(agc_enabled, agc_mode);
3257 voe_.GetNsStatus(ns_enabled, ns_mode);
3258 EXPECT_TRUE(ec_enabled);
3259 EXPECT_FALSE(agc_enabled);
3260 EXPECT_FALSE(ns_enabled);
3261}
3262
wu@webrtc.orgde305012013-10-31 15:40:38 +00003263// This test verifies DSCP settings are properly applied on voice media channel.
3264TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003265 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003266 cricket::FakeNetworkInterface network_interface;
3267 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003268 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003269
solenberg059fb442016-10-26 05:12:24 -07003270 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3271 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3272
solenbergbc37fc82016-04-04 09:54:44 -07003273 channel.reset(
3274 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003275 channel->SetInterface(&network_interface);
3276 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3277 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3278
3279 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003280 channel.reset(
3281 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003282 channel->SetInterface(&network_interface);
3283 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3284
3285 // Verify that setting the option to false resets the
3286 // DiffServCodePoint.
3287 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003288 channel.reset(
3289 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003290 channel->SetInterface(&network_interface);
3291 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3292 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3293
3294 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003295}
3296
solenberg1ac56142015-10-13 03:58:19 -07003297TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003298 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003299 cricket::WebRtcVoiceMediaChannel* media_channel =
3300 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003301 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003302 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003303 int channel_id = voe_.GetLastChannel();
3304 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3305 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003306 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003307 int channel_id2 = voe_.GetLastChannel();
3308 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003309}
3310
solenberg1ac56142015-10-13 03:58:19 -07003311TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003312 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003313 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003314 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3315 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3316 EXPECT_TRUE(channel_->AddSendStream(
3317 cricket::StreamParams::CreateLegacy(kSsrc1)));
3318 int channel_id = voe_.GetLastChannel();
3319 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3320 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3321 EXPECT_TRUE(channel_->AddSendStream(
3322 cricket::StreamParams::CreateLegacy(kSsrc2)));
3323 int channel_id2 = voe_.GetLastChannel();
3324 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003325}
3326
solenberg4bac9c52015-10-09 02:32:53 -07003327TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003328 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003329 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003330 cricket::StreamParams stream;
3331 stream.ssrcs.push_back(kSsrc2);
3332 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003333 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003334 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003335 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003336}
3337
3338TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003339 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003340 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3341 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003342 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003343 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003344 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3345 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3346 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003347}
3348
pbos8fc7fa72015-07-15 08:02:58 -07003349TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003350 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003351 const std::string kSyncLabel = "AvSyncLabel";
3352
solenbergff976312016-03-30 23:28:51 -07003353 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003354 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3355 sp.sync_label = kSyncLabel;
3356 // Creating two channels to make sure that sync label is set properly for both
3357 // the default voice channel and following ones.
3358 EXPECT_TRUE(channel_->AddRecvStream(sp));
3359 sp.ssrcs[0] += 1;
3360 EXPECT_TRUE(channel_->AddRecvStream(sp));
3361
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003362 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003363 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003364 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003365 << "SyncGroup should be set based on sync_label";
3366 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003367 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003368 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003369}
3370
solenberg3a941542015-11-16 07:34:50 -08003371// TODO(solenberg): Remove, once recv streams are configured through Call.
3372// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003373TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374 // Test that setting the header extensions results in the expected state
3375 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003376 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003377 ssrcs.push_back(223);
3378 ssrcs.push_back(224);
3379
solenbergff976312016-03-30 23:28:51 -07003380 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003381 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003382 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003383 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003384 cricket::StreamParams::CreateLegacy(ssrc)));
3385 }
3386
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003387 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003388 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003389 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003390 EXPECT_NE(nullptr, s);
3391 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3392 }
3393
3394 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003395 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003396 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003397 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003398 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003399 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003400 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003401 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003402 EXPECT_NE(nullptr, s);
3403 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003404 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3405 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003406 for (const auto& s_ext : s_exts) {
3407 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003408 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003409 }
3410 }
3411 }
3412 }
3413
3414 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003415 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003416 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003417 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003418 EXPECT_NE(nullptr, s);
3419 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3420 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003421}
3422
3423TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3424 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003425 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003426 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003427 static const unsigned char kRtcp[] = {
3428 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3429 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3432 };
jbaucheec21bd2016-03-20 06:15:43 -07003433 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003434
solenbergff976312016-03-30 23:28:51 -07003435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003436 cricket::WebRtcVoiceMediaChannel* media_channel =
3437 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003438 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003439 EXPECT_TRUE(media_channel->AddRecvStream(
3440 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3441
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003442 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003443 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003444 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003445 EXPECT_EQ(0, s->received_packets());
3446 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3447 EXPECT_EQ(1, s->received_packets());
3448 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3449 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003450}
Minyue2013aec2015-05-13 14:14:42 +02003451
solenberg0a617e22015-10-20 15:49:38 -07003452// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003453// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003454TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003455 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003456 EXPECT_TRUE(AddRecvStream(kSsrc2));
3457 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3458 EXPECT_TRUE(channel_->AddSendStream(
3459 cricket::StreamParams::CreateLegacy(kSsrc3)));
3460 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3461 EXPECT_TRUE(AddRecvStream(kSsrc4));
3462 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003463}
3464
solenberg7602aab2016-11-14 11:30:07 -08003465TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3466 EXPECT_TRUE(SetupRecvStream());
3467 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3468 EXPECT_TRUE(channel_->AddSendStream(
3469 cricket::StreamParams::CreateLegacy(kSsrc2)));
3470 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3471 EXPECT_TRUE(AddRecvStream(kSsrc3));
3472 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3473 EXPECT_TRUE(channel_->AddSendStream(
3474 cricket::StreamParams::CreateLegacy(kSsrc4)));
3475 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3476 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003477}
stefan658910c2015-09-03 05:48:32 -07003478
deadbeef884f5852016-01-15 09:20:04 -08003479TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003480 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003481 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3482 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003483
3484 // Setting the sink before a recv stream exists should do nothing.
3485 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003486 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003487 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3488
3489 // Now try actually setting the sink.
3490 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3491 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3492
3493 // Now try resetting it.
3494 channel_->SetRawAudioSink(kSsrc1, nullptr);
3495 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3496}
3497
3498TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003499 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003500 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3501 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003502
3503 // Should be able to set a default sink even when no stream exists.
3504 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3505
3506 // Create default channel and ensure it's assigned the default sink.
3507 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3508 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3509
3510 // Try resetting the default sink.
3511 channel_->SetRawAudioSink(0, nullptr);
3512 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3513
3514 // Try setting the default sink while the default stream exists.
3515 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3516 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3517
3518 // If we remove and add a default stream, it should get the same sink.
3519 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3520 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3521 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3522}
3523
skvlad7a43d252016-03-22 15:32:27 -07003524// Test that, just like the video channel, the voice channel communicates the
3525// network state to the call.
3526TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003527 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003528
3529 EXPECT_EQ(webrtc::kNetworkUp,
3530 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3531 EXPECT_EQ(webrtc::kNetworkUp,
3532 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3533
3534 channel_->OnReadyToSend(false);
3535 EXPECT_EQ(webrtc::kNetworkDown,
3536 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3537 EXPECT_EQ(webrtc::kNetworkUp,
3538 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3539
3540 channel_->OnReadyToSend(true);
3541 EXPECT_EQ(webrtc::kNetworkUp,
3542 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3543 EXPECT_EQ(webrtc::kNetworkUp,
3544 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3545}
3546
aleloi18e0b672016-10-04 02:45:47 -07003547// Test that playout is still started after changing parameters
3548TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3549 SetupRecvStream();
3550 channel_->SetPlayout(true);
3551 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3552
3553 // Changing RTP header extensions will recreate the AudioReceiveStream.
3554 cricket::AudioRecvParameters parameters;
3555 parameters.extensions.push_back(
3556 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3557 channel_->SetRecvParameters(parameters);
3558
3559 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3560}
3561
stefan658910c2015-09-03 05:48:32 -07003562// Tests that the library initializes and shuts down properly.
3563TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003564 // If the VoiceEngine wants to gather available codecs early, that's fine but
3565 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003566 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003567 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003568 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003569 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003570 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003571 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3572 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003573 EXPECT_TRUE(channel != nullptr);
3574 delete channel;
solenbergff976312016-03-30 23:28:51 -07003575}
stefan658910c2015-09-03 05:48:32 -07003576
solenbergff976312016-03-30 23:28:51 -07003577// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003578TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3579 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3580 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3581 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003582 {
ossuc54071d2016-08-17 02:45:41 -07003583 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003584 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003585 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003586 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003587 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003588 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3589 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3590 EXPECT_TRUE(channel != nullptr);
3591 delete channel;
3592 }
stefan658910c2015-09-03 05:48:32 -07003593}
3594
3595// Tests that the library is configured with the codecs we want.
3596TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003597 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3598 // module.
3599
stefan658910c2015-09-03 05:48:32 -07003600 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003601#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003602 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003603 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003604#endif
3605#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003606 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003607 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003608#endif
3609#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003610 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003611 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003612#endif
3613#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003614 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003615 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003616 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003617 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003618 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003619#endif
solenberg26c8c912015-11-27 04:00:25 -08003620 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003621 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003622 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003623 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003624 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003625 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003626 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3627 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3628 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3629 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3630 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3631 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003632 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003633 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003634 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003635 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003636 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003637 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003638 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003639 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003640 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003641 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003642 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003643 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003644 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003649 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003650 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003651 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003652 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003653 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003654 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003655
stefan658910c2015-09-03 05:48:32 -07003656 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003657 // TODO(ossu): Why are the payload types of codecs with non-static payload
3658 // type assignments checked here? It shouldn't really matter.
3659 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003660 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003661 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3662 if (codec.name == "CN" && codec.clockrate == 16000) {
3663 EXPECT_EQ(105, codec.id);
3664 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3665 EXPECT_EQ(106, codec.id);
3666 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3667 EXPECT_EQ(103, codec.id);
3668 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3669 EXPECT_EQ(104, codec.id);
3670 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3671 EXPECT_EQ(9, codec.id);
3672 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3673 EXPECT_EQ(126, codec.id);
3674 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3675 // Remove these checks once both send and receive side assigns payload types
3676 // dynamically.
3677 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3678 EXPECT_EQ(113, codec.id);
3679 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3680 EXPECT_EQ(112, codec.id);
3681 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3682 EXPECT_EQ(110, codec.id);
3683 } else if (codec.name == "opus") {
3684 EXPECT_EQ(111, codec.id);
3685 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3686 EXPECT_EQ("10", codec.params.find("minptime")->second);
3687 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3688 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003689 }
3690 }
stefan658910c2015-09-03 05:48:32 -07003691}
3692
3693// Tests that VoE supports at least 32 channels
3694TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003695 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003696 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003697 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003698 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003699 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003700
3701 cricket::VoiceMediaChannel* channels[32];
3702 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003703 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003704 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3705 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003706 if (!channel)
3707 break;
stefan658910c2015-09-03 05:48:32 -07003708 channels[num_channels++] = channel;
3709 }
3710
tfarina5237aaf2015-11-10 23:44:30 -08003711 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003712 EXPECT_EQ(expected, num_channels);
3713
3714 while (num_channels > 0) {
3715 delete channels[--num_channels];
3716 }
stefan658910c2015-09-03 05:48:32 -07003717}
3718
3719// Test that we set our preferred codecs properly.
3720TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003721 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3722 // - Check that our builtin codecs are usable by Channel.
3723 // - The codecs provided by the engine is usable by Channel.
3724 // It does not check that the codecs in the RecvParameters are actually
3725 // what we sent in - though it's probably reasonable to expect so, if
3726 // SetRecvParameters returns true.
3727 // I think it will become clear once audio decoder injection is completed.
3728 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003729 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003730 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003731 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003732 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003733 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3734 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003735 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003736 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003737 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003738}
ossu9def8002017-02-09 05:14:32 -08003739
3740TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3741 std::vector<webrtc::AudioCodecSpec> specs;
3742 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3743 spec1.allow_comfort_noise = false;
3744 spec1.supports_network_adaption = true;
3745 specs.push_back(spec1);
3746 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3747 spec2.allow_comfort_noise = false;
3748 specs.push_back(spec2);
3749 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3750 {{"param1", "value1b"},
3751 {"param2", "value2"}}}));
3752 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3753 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3754
3755 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3756 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3757 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3758 .WillOnce(Return(specs));
3759
3760 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3761 auto codecs = engine.recv_codecs();
3762 EXPECT_EQ(11, codecs.size());
3763
3764 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3765 // check the actual values safely, to provide better test results.
3766 auto get_codec =
3767 [&codecs](size_t index) -> const cricket::AudioCodec& {
3768 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3769 if (codecs.size() > index)
3770 return codecs[index];
3771 return missing_codec;
3772 };
3773
3774 // Ensure the general codecs are generated first and in order.
3775 for (size_t i = 0; i != specs.size(); ++i) {
3776 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3777 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3778 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3779 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3780 }
3781
3782 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003783 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003784 auto find_codec =
3785 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3786 for (size_t i = 0; i != codecs.size(); ++i) {
3787 const cricket::AudioCodec& codec = codecs[i];
3788 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3789 codec.clockrate == format.clockrate_hz &&
3790 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003791 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003792 }
3793 }
3794 return -1;
3795 };
3796
3797 // Ensure all supplementary codecs are generated last. Their internal ordering
3798 // is not important.
3799 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3800 const int num_specs = static_cast<int>(specs.size());
3801 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3802 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3803 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3804 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3805 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3806 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3807 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3808}