blob: a08ac6a92e24ad744fe3adcd48b1a91467f8fbff [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"
ossubcd88db2017-02-13 07:04:05 -080016#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070018#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakemediaengine.h"
20#include "webrtc/media/base/fakenetworkinterface.h"
21#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080022#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010023#include "webrtc/media/engine/fakewebrtccall.h"
24#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
25#include "webrtc/media/engine/webrtcvoiceengine.h"
ossu29b1a8d2016-06-13 07:34:51 -070026#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070027#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070028#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080029#include "webrtc/pc/channel.h"
30#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080031#include "webrtc/test/gtest.h"
32#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
solenbergbc37fc82016-04-04 09:54:44 -070034using testing::Return;
35using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000036
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020037namespace {
38
deadbeef67cf2c12016-04-13 10:07:16 -070039const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
40const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
41const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
42const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
43const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070044const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
45const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080046const cricket::AudioCodec
47 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
48const cricket::AudioCodec
49 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
50
solenberg85a04962015-10-27 03:35:21 -070051const uint32_t kSsrc1 = 0x99;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080052const uint32_t kSsrc2 = 2;
53const uint32_t kSsrc3 = 3;
solenberg7602aab2016-11-14 11:30:07 -080054const uint32_t kSsrc4 = 0x42;
solenberg85a04962015-10-27 03:35:21 -070055const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056
solenberg971cab02016-06-14 10:02:41 -070057constexpr int kRtpHistoryMs = 5000;
58
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059class FakeVoEWrapper : public cricket::VoEWrapper {
60 public:
61 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg76377c52017-02-21 00:54:31 -080062 : cricket::VoEWrapper(engine, // base
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063 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
solenberg76377c52017-02-21 00:54:31 -080069class MockTransmitMixer : public webrtc::voe::TransmitMixer {
70 public:
71 MockTransmitMixer() = default;
72 virtual ~MockTransmitMixer() = default;
73
74 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
75};
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020076} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077
solenbergff976312016-03-30 23:28:51 -070078// Tests that our stub library "works".
79TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070080 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
81 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
82 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070083 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
84 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
85 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -080086 EXPECT_CALL(adm, SetAGC(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -070087 StrictMock<webrtc::test::MockAudioProcessing> apm;
88 EXPECT_CALL(apm, ApplyConfig(testing::_));
89 EXPECT_CALL(apm, SetExtraOptions(testing::_));
90 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -080091 StrictMock<MockTransmitMixer> transmit_mixer;
92 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
93 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -070094 EXPECT_FALSE(voe.IsInited());
95 {
ossuc54071d2016-08-17 02:45:41 -070096 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -080097 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -070098 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -070099 EXPECT_TRUE(voe.IsInited());
100 }
101 EXPECT_FALSE(voe.IsInited());
102}
103
deadbeef884f5852016-01-15 09:20:04 -0800104class FakeAudioSink : public webrtc::AudioSinkInterface {
105 public:
106 void OnData(const Data& audio) override {}
107};
108
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800109class FakeAudioSource : public cricket::AudioSource {
110 void SetSink(Sink* sink) override {}
111};
112
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000113class WebRtcVoiceEngineTestFake : public testing::Test {
114 public:
stefanba4c0e42016-02-04 04:12:24 -0800115 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
116
117 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800118 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
119 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
120 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700121 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800122 // AudioDeviceModule.
solenbergbc37fc82016-04-04 09:54:44 -0700123 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
124 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700125 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
126 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
127 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -0800128 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
129 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700130 EXPECT_CALL(apm_, ApplyConfig(testing::_));
131 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
132 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800133 // Default Options.
134 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
135 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
136 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
137 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
138 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
139 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
140 // Init does not overwrite default AGC config.
141 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
142 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
143 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
144 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
145 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
146 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800147 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
148 // the tests here probe the specific set of codecs provided by the builtin
149 // factory. Those tests should probably be moved elsewhere.
150 engine_.reset(new cricket::WebRtcVoiceEngine(
151 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
152 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200153 send_parameters_.codecs.push_back(kPcmuCodec);
154 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800155 // Default Options.
156 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 }
solenberg8189b022016-06-14 12:13:00 -0700158
solenbergff976312016-03-30 23:28:51 -0700159 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700160 EXPECT_CALL(apm_, ApplyConfig(testing::_));
161 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700162 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
163 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200164 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000165 }
solenberg8189b022016-06-14 12:13:00 -0700166
solenbergff976312016-03-30 23:28:51 -0700167 bool SetupRecvStream() {
168 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700169 return false;
170 }
solenberg8189b022016-06-14 12:13:00 -0700171 return AddRecvStream(kSsrc1);
solenberg1ac56142015-10-13 03:58:19 -0700172 }
solenberg8189b022016-06-14 12:13:00 -0700173
solenbergff976312016-03-30 23:28:51 -0700174 bool SetupSendStream() {
175 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000176 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177 }
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800178 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1))) {
179 return false;
180 }
solenberg059fb442016-10-26 05:12:24 -0700181 EXPECT_CALL(apm_, set_output_will_be_muted(false));
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800182 return channel_->SetAudioSend(kSsrc1, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000183 }
solenberg8189b022016-06-14 12:13:00 -0700184
185 bool AddRecvStream(uint32_t ssrc) {
186 EXPECT_TRUE(channel_);
187 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
188 }
189
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000190 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700191 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700192 // Remove stream added in Setup.
solenberg3a941542015-11-16 07:34:50 -0800193 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg85a04962015-10-27 03:35:21 -0700194 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
solenberg0a617e22015-10-20 15:49:38 -0700195 // Verify the channel does not exist.
solenberg3a941542015-11-16 07:34:50 -0800196 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000197 }
solenberg8189b022016-06-14 12:13:00 -0700198
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700200 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000201 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 }
solenberg8189b022016-06-14 12:13:00 -0700203
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200204 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 }
207
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100208 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
209 const auto* send_stream = call_.GetAudioSendStream(ssrc);
210 EXPECT_TRUE(send_stream);
211 return *send_stream;
212 }
213
deadbeef884f5852016-01-15 09:20:04 -0800214 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
215 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
216 EXPECT_TRUE(recv_stream);
217 return *recv_stream;
218 }
219
solenberg3a941542015-11-16 07:34:50 -0800220 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800221 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800222 }
223
solenberg7add0582015-11-20 09:59:34 -0800224 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800225 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800226 }
227
solenberg059fb442016-10-26 05:12:24 -0700228 void SetSend(bool enable) {
229 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700230 if (enable) {
231 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
232 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
233 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700234 EXPECT_CALL(apm_, ApplyConfig(testing::_));
235 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700236 }
solenberg059fb442016-10-26 05:12:24 -0700237 channel_->SetSend(enable);
238 }
239
240 void SetSendParameters(const cricket::AudioSendParameters& params) {
241 EXPECT_CALL(apm_, ApplyConfig(testing::_));
242 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
243 ASSERT_TRUE(channel_);
244 EXPECT_TRUE(channel_->SetSendParameters(params));
245 }
246
minyue6b825df2016-10-31 04:08:32 -0700247 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
248 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700249 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
250 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700251 if (enable && options) {
252 EXPECT_CALL(apm_, ApplyConfig(testing::_));
253 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
254 }
255 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700256 }
257
solenbergffbbcac2016-11-17 05:25:37 -0800258 void TestInsertDtmf(uint32_t ssrc, bool caller,
259 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700260 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000261 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700262 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000263 // send stream.
264 EXPECT_TRUE(channel_->AddSendStream(
265 cricket::StreamParams::CreateLegacy(kSsrc1)));
266 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000267
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700269 SetSendParameters(send_parameters_);
270 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800272 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800273 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700274 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000276
277 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700278 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800279 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000280 EXPECT_TRUE(channel_->AddSendStream(
281 cricket::StreamParams::CreateLegacy(kSsrc1)));
282 }
283
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800285 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100287 // Test send.
288 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
289 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
290 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800291 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100292 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800293 EXPECT_EQ(codec.id, telephone_event.payload_type);
294 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100295 EXPECT_EQ(2, telephone_event.event_code);
296 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000297 }
298
299 // Test that send bandwidth is set correctly.
300 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000301 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
302 // |expected_result| is the expected result from SetMaxSendBandwidth().
303 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700304 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
305 int max_bitrate,
306 bool expected_result,
307 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200308 cricket::AudioSendParameters parameters;
309 parameters.codecs.push_back(codec);
310 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700311 if (expected_result) {
312 SetSendParameters(parameters);
313 } else {
314 EXPECT_FALSE(channel_->SetSendParameters(parameters));
315 }
minyue7a973442016-10-20 03:27:12 -0700316 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 }
318
skvlade0d46372016-04-07 22:59:22 -0700319 // Sets the per-stream maximum bitrate limit for the specified SSRC.
320 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700321 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700322 EXPECT_EQ(1UL, parameters.encodings.size());
323
deadbeefe702b302017-02-04 12:09:01 -0800324 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700325 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700326 }
327
solenberg059fb442016-10-26 05:12:24 -0700328 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700329 cricket::AudioSendParameters send_parameters;
330 send_parameters.codecs.push_back(codec);
331 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700332 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700333 }
334
minyue7a973442016-10-20 03:27:12 -0700335 void CheckSendCodec(int32_t ssrc,
336 const char expected_name[],
337 int expected_channels,
338 int expected_bitrate) {
339 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
340 EXPECT_STREQ(expected_name, codec.plname);
341 EXPECT_EQ(expected_channels, codec.channels);
342 EXPECT_EQ(expected_bitrate, codec.rate);
343 }
344
345 int GetOpusMaxPlaybackRate(int32_t ssrc) {
346 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
347 }
348
349 bool GetOpusDtx(int32_t ssrc) {
350 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
351 }
352
353 bool GetCodecFec(int32_t ssrc) {
354 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
355 }
356
skvlade0d46372016-04-07 22:59:22 -0700357 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700358 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
359 }
360
361 int GetCodecPacSize(int32_t ssrc) {
362 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700363 }
364
minyue6b825df2016-10-31 04:08:32 -0700365 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
366 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
367 }
368
skvlade0d46372016-04-07 22:59:22 -0700369 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
370 int global_max,
371 int stream_max,
372 bool expected_result,
373 int expected_codec_bitrate) {
374 // Clear the bitrate limit from the previous test case.
375 EXPECT_TRUE(SetMaxBitrateForStream(kSsrc1, -1));
376
377 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700378 SetGlobalMaxBitrate(codec, global_max);
skvlade0d46372016-04-07 22:59:22 -0700379 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrc1, stream_max));
380
381 // Verify that reading back the parameters gives results
382 // consistent with the Set() result.
383 webrtc::RtpParameters resulting_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700384 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -0700385 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
386 EXPECT_EQ(expected_result ? stream_max : -1,
387 resulting_parameters.encodings[0].max_bitrate_bps);
388
389 // Verify that the codec settings have the expected bitrate.
390 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrc1));
391 }
392
stefan13f1a0a2016-11-30 07:22:58 -0800393 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
394 int expected_min_bitrate_bps,
395 const char* start_bitrate_kbps,
396 int expected_start_bitrate_bps,
397 const char* max_bitrate_kbps,
398 int expected_max_bitrate_bps) {
399 EXPECT_TRUE(SetupSendStream());
400 auto& codecs = send_parameters_.codecs;
401 codecs.clear();
402 codecs.push_back(kOpusCodec);
403 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
404 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
405 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
406 SetSendParameters(send_parameters_);
407
408 EXPECT_EQ(expected_min_bitrate_bps,
409 call_.GetConfig().bitrate_config.min_bitrate_bps);
410 EXPECT_EQ(expected_start_bitrate_bps,
411 call_.GetConfig().bitrate_config.start_bitrate_bps);
412 EXPECT_EQ(expected_max_bitrate_bps,
413 call_.GetConfig().bitrate_config.max_bitrate_bps);
414 }
415
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000416 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700417 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000418
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000419 // Ensure extensions are off by default.
solenberg3a941542015-11-16 07:34:50 -0800420 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000421
422 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700423 send_parameters_.extensions.push_back(
424 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700425 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800426 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000427
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000428 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200429 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700430 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800431 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000432
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000433 // Ensure extension is set properly.
434 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700435 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700436 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800437 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700438 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800439 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000440
solenberg7add0582015-11-20 09:59:34 -0800441 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000442 EXPECT_TRUE(channel_->AddSendStream(
solenberg0a617e22015-10-20 15:49:38 -0700443 cricket::StreamParams::CreateLegacy(kSsrc2)));
solenberg3a941542015-11-16 07:34:50 -0800444 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
445 call_.GetAudioSendStream(kSsrc2));
446 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700447 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg3a941542015-11-16 07:34:50 -0800448 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449
450 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200451 send_parameters_.codecs.push_back(kPcmuCodec);
452 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700453 SetSendParameters(send_parameters_);
solenberg3a941542015-11-16 07:34:50 -0800454 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
455 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000456 }
457
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000458 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700459 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000460
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000461 // Ensure extensions are off by default.
solenberg7add0582015-11-20 09:59:34 -0800462 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000463
464 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700465 recv_parameters_.extensions.push_back(
466 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800467 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
468 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000469
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000470 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800471 recv_parameters_.extensions.clear();
472 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
473 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000474
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000475 // Ensure extension is set properly.
476 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700477 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800478 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
479 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700480 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800481 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482
solenberg7add0582015-11-20 09:59:34 -0800483 // Ensure extension is set properly on new stream.
solenberg8189b022016-06-14 12:13:00 -0700484 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -0800485 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
486 call_.GetAudioReceiveStream(kSsrc2));
487 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -0700488 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].uri);
solenberg7add0582015-11-20 09:59:34 -0800489 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000490
491 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800492 recv_parameters_.extensions.clear();
493 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
494 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
495 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000496 }
497
solenberg85a04962015-10-27 03:35:21 -0700498 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
499 webrtc::AudioSendStream::Stats stats;
500 stats.local_ssrc = 12;
501 stats.bytes_sent = 345;
502 stats.packets_sent = 678;
503 stats.packets_lost = 9012;
504 stats.fraction_lost = 34.56f;
505 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800506 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700507 stats.ext_seqnum = 789;
508 stats.jitter_ms = 12;
509 stats.rtt_ms = 345;
510 stats.audio_level = 678;
511 stats.aec_quality_min = 9.01f;
512 stats.echo_delay_median_ms = 234;
513 stats.echo_delay_std_ms = 567;
514 stats.echo_return_loss = 890;
515 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700516 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800517 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700518 stats.typing_noise_detected = true;
519 return stats;
520 }
521 void SetAudioSendStreamStats() {
522 for (auto* s : call_.GetAudioSendStreams()) {
523 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200524 }
solenberg85a04962015-10-27 03:35:21 -0700525 }
solenberg566ef242015-11-06 15:34:49 -0800526 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
527 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700528 const auto stats = GetAudioSendStreamStats();
529 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
530 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
531 EXPECT_EQ(info.packets_sent, stats.packets_sent);
532 EXPECT_EQ(info.packets_lost, stats.packets_lost);
533 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
534 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800535 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700536 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
537 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
538 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
539 EXPECT_EQ(info.audio_level, stats.audio_level);
540 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
541 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
542 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
543 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
544 EXPECT_EQ(info.echo_return_loss_enhancement,
545 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700546 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800547 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
548 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800549 EXPECT_EQ(info.typing_noise_detected,
550 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700551 }
552
553 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
554 webrtc::AudioReceiveStream::Stats stats;
555 stats.remote_ssrc = 123;
556 stats.bytes_rcvd = 456;
557 stats.packets_rcvd = 768;
558 stats.packets_lost = 101;
559 stats.fraction_lost = 23.45f;
560 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800561 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700562 stats.ext_seqnum = 678;
563 stats.jitter_ms = 901;
564 stats.jitter_buffer_ms = 234;
565 stats.jitter_buffer_preferred_ms = 567;
566 stats.delay_estimate_ms = 890;
567 stats.audio_level = 1234;
568 stats.expand_rate = 5.67f;
569 stats.speech_expand_rate = 8.90f;
570 stats.secondary_decoded_rate = 1.23f;
571 stats.accelerate_rate = 4.56f;
572 stats.preemptive_expand_rate = 7.89f;
573 stats.decoding_calls_to_silence_generator = 12;
574 stats.decoding_calls_to_neteq = 345;
575 stats.decoding_normal = 67890;
576 stats.decoding_plc = 1234;
577 stats.decoding_cng = 5678;
578 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700579 stats.decoding_muted_output = 3456;
580 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200581 return stats;
582 }
583 void SetAudioReceiveStreamStats() {
584 for (auto* s : call_.GetAudioReceiveStreams()) {
585 s->SetStats(GetAudioReceiveStreamStats());
586 }
587 }
588 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700589 const auto stats = GetAudioReceiveStreamStats();
590 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
591 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
592 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
593 EXPECT_EQ(info.packets_lost, stats.packets_lost);
594 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
595 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800596 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700597 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
598 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
599 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200600 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700601 stats.jitter_buffer_preferred_ms);
602 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
603 EXPECT_EQ(info.audio_level, stats.audio_level);
604 EXPECT_EQ(info.expand_rate, stats.expand_rate);
605 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
606 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
607 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
608 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200609 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700610 stats.decoding_calls_to_silence_generator);
611 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
612 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
613 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
614 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
615 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700616 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700617 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200618 }
hbos1acfbd22016-11-17 23:43:29 -0800619 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
620 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
621 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
622 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
623 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
624 codec.ToCodecParameters());
625 }
626 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
627 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
628 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
629 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
630 codec.ToCodecParameters());
631 }
632 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200633
peah8271d042016-11-22 07:24:52 -0800634 bool IsHighPassFilterEnabled() {
635 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
636 }
637
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000638 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700639 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700640 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800641 webrtc::test::MockGainControl& apm_gc_;
642 webrtc::test::MockEchoCancellation& apm_ec_;
643 webrtc::test::MockNoiseSuppression& apm_ns_;
644 webrtc::test::MockVoiceDetection& apm_vd_;
645 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700646 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200647 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700649 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700650 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200651 cricket::AudioSendParameters send_parameters_;
652 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800653 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800654 private:
655 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656};
657
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658// Tests that we can create and destroy a channel.
659TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700660 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661}
662
solenberg31fec402016-05-06 02:13:12 -0700663// Test that we can add a send stream and that it has the correct defaults.
664TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
665 EXPECT_TRUE(SetupChannel());
666 EXPECT_TRUE(
667 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
668 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrc1);
669 EXPECT_EQ(kSsrc1, config.rtp.ssrc);
670 EXPECT_EQ("", config.rtp.c_name);
671 EXPECT_EQ(0u, config.rtp.extensions.size());
672 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
673 config.send_transport);
674}
675
676// Test that we can add a receive stream and that it has the correct defaults.
677TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
678 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -0700679 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg31fec402016-05-06 02:13:12 -0700680 const webrtc::AudioReceiveStream::Config& config =
681 GetRecvStreamConfig(kSsrc1);
682 EXPECT_EQ(kSsrc1, config.rtp.remote_ssrc);
683 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
684 EXPECT_FALSE(config.rtp.transport_cc);
685 EXPECT_EQ(0u, config.rtp.extensions.size());
686 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
687 config.rtcp_send_transport);
688 EXPECT_EQ("", config.sync_group);
689}
690
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700692// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700693// TODO(ossu): This test should move into a separate builtin audio codecs
694// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700695TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700696 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000697 ASSERT_FALSE(codecs.empty());
698 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
699 EXPECT_EQ(48000, codecs[0].clockrate);
700 EXPECT_EQ(2, codecs[0].channels);
701 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702}
703
stefanba4c0e42016-02-04 04:12:24 -0800704TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700705 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800706 bool opus_found = false;
707 for (cricket::AudioCodec codec : codecs) {
708 if (codec.name == "opus") {
709 EXPECT_TRUE(HasTransportCc(codec));
710 opus_found = true;
711 }
712 }
713 EXPECT_TRUE(opus_found);
714}
715
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716// Tests that we can find codecs by name or id, and that we interpret the
717// clockrate and bitrate fields properly.
718TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
719 cricket::AudioCodec codec;
720 webrtc::CodecInst codec_inst;
721 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800722 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800724 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800726 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
727 &codec_inst));
728 // Find telephone-event with explicit clockrate and 0 bitrate.
729 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800730 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 // Find ISAC with a different payload id.
732 codec = kIsacCodec;
733 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800734 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735 EXPECT_EQ(codec.id, codec_inst.pltype);
736 // Find PCMU with a 0 clockrate.
737 codec = kPcmuCodec;
738 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800739 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 EXPECT_EQ(codec.id, codec_inst.pltype);
741 EXPECT_EQ(8000, codec_inst.plfreq);
742 // Find PCMU with a 0 bitrate.
743 codec = kPcmuCodec;
744 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800745 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746 EXPECT_EQ(codec.id, codec_inst.pltype);
747 EXPECT_EQ(64000, codec_inst.rate);
748 // Find ISAC with an explicit bitrate.
749 codec = kIsacCodec;
750 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800751 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000752 EXPECT_EQ(codec.id, codec_inst.pltype);
753 EXPECT_EQ(32000, codec_inst.rate);
754}
755
756// Test that we set our inbound codecs properly, including changing PT.
757TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700758 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200759 cricket::AudioRecvParameters parameters;
760 parameters.codecs.push_back(kIsacCodec);
761 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800762 parameters.codecs.push_back(kTelephoneEventCodec1);
763 parameters.codecs.push_back(kTelephoneEventCodec2);
764 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200765 parameters.codecs[2].id = 126;
766 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700767 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700768 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800769
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800771 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772 gcodec.plfreq = 16000;
773 gcodec.channels = 1;
774 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
775 EXPECT_EQ(106, gcodec.pltype);
776 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800777
tfarina5237aaf2015-11-10 23:44:30 -0800778 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779 gcodec.plfreq = 8000;
780 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
781 EXPECT_EQ(126, gcodec.pltype);
782 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800783
784 gcodec.plfreq = 32000;
785 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
786 EXPECT_EQ(107, gcodec.pltype);
787 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788}
789
790// Test that we fail to set an unknown inbound codec.
791TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700792 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200793 cricket::AudioRecvParameters parameters;
794 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700795 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000797}
798
799// Test that we fail if we have duplicate types in the inbound list.
800TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700801 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200802 cricket::AudioRecvParameters parameters;
803 parameters.codecs.push_back(kIsacCodec);
804 parameters.codecs.push_back(kCn16000Codec);
805 parameters.codecs[1].id = kIsacCodec.id;
806 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807}
808
809// Test that we can decode OPUS without stereo parameters.
810TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700811 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 cricket::AudioRecvParameters parameters;
813 parameters.codecs.push_back(kIsacCodec);
814 parameters.codecs.push_back(kPcmuCodec);
815 parameters.codecs.push_back(kOpusCodec);
816 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700817 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -0700818 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800820 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821 // Even without stereo parameters, recv codecs still specify channels = 2.
822 EXPECT_EQ(2, opus.channels);
823 EXPECT_EQ(111, opus.pltype);
824 EXPECT_STREQ("opus", opus.plname);
825 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700826 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827 EXPECT_EQ(111, opus.pltype);
828}
829
830// Test that we can decode OPUS with stereo = 0.
831TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700832 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200833 cricket::AudioRecvParameters parameters;
834 parameters.codecs.push_back(kIsacCodec);
835 parameters.codecs.push_back(kPcmuCodec);
836 parameters.codecs.push_back(kOpusCodec);
837 parameters.codecs[2].params["stereo"] = "0";
838 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700839 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840 int channel_num2 = voe_.GetLastChannel();
841 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800842 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843 // Even when stereo is off, recv codecs still specify channels = 2.
844 EXPECT_EQ(2, opus.channels);
845 EXPECT_EQ(111, opus.pltype);
846 EXPECT_STREQ("opus", opus.plname);
847 opus.pltype = 0;
848 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
849 EXPECT_EQ(111, opus.pltype);
850}
851
852// Test that we can decode OPUS with stereo = 1.
853TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700854 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 cricket::AudioRecvParameters parameters;
856 parameters.codecs.push_back(kIsacCodec);
857 parameters.codecs.push_back(kPcmuCodec);
858 parameters.codecs.push_back(kOpusCodec);
859 parameters.codecs[2].params["stereo"] = "1";
860 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700861 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862 int channel_num2 = voe_.GetLastChannel();
863 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800864 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865 EXPECT_EQ(2, opus.channels);
866 EXPECT_EQ(111, opus.pltype);
867 EXPECT_STREQ("opus", opus.plname);
868 opus.pltype = 0;
869 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
870 EXPECT_EQ(111, opus.pltype);
871}
872
873// Test that changes to recv codecs are applied to all streams.
874TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700875 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200876 cricket::AudioRecvParameters parameters;
877 parameters.codecs.push_back(kIsacCodec);
878 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800879 parameters.codecs.push_back(kTelephoneEventCodec1);
880 parameters.codecs.push_back(kTelephoneEventCodec2);
881 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200882 parameters.codecs[2].id = 126;
883 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -0700884 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800886
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800888 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889 gcodec.plfreq = 16000;
890 gcodec.channels = 1;
891 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
892 EXPECT_EQ(106, gcodec.pltype);
893 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800894
tfarina5237aaf2015-11-10 23:44:30 -0800895 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 gcodec.plfreq = 8000;
897 gcodec.channels = 1;
898 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
899 EXPECT_EQ(126, gcodec.pltype);
900 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800901
902 gcodec.plfreq = 32000;
903 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
904 EXPECT_EQ(107, gcodec.pltype);
905 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906}
907
908TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700909 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200910 cricket::AudioRecvParameters parameters;
911 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800912 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
kwibergd32bf752017-01-19 07:03:59 -0800915 const auto& dm = GetRecvStreamConfig(kSsrc1).decoder_map;
916 ASSERT_EQ(1, dm.count(106));
917 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
920// Test that we can apply the same set of codecs again while playing.
921TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700922 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200923 cricket::AudioRecvParameters parameters;
924 parameters.codecs.push_back(kIsacCodec);
925 parameters.codecs.push_back(kCn16000Codec);
926 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700927 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929
930 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 parameters.codecs[0].id = 127;
932 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700933 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934}
935
936// Test that we can add a codec while playing.
937TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 cricket::AudioRecvParameters parameters;
940 parameters.codecs.push_back(kIsacCodec);
941 parameters.codecs.push_back(kCn16000Codec);
942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700943 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 parameters.codecs.push_back(kOpusCodec);
946 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700947 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800949 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
951}
952
953TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000956 // Test that when autobw is enabled, bitrate is kept as the default
957 // value. autobw is enabled for the following tests because the target
958 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959
960 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700961 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
963 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700967 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000970TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000973 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
975 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
977 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
978 // Rates above the max (56000) should be capped.
979 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700982 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
983 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
984 // Rates above the max (510000) should be capped.
985 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986}
987
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000988TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700989 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990
991 // Test that we can only set a maximum bitrate for a fixed-rate codec
992 // if it's bigger than the fixed rate.
993
994 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700995 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
996 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1000 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1001 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002}
1003
1004TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001005 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001006 const int kDesiredBitrate = 128000;
1007 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001008 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001010 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001011
1012 EXPECT_TRUE(channel_->AddSendStream(
1013 cricket::StreamParams::CreateLegacy(kSsrc1)));
1014
minyue7a973442016-10-20 03:27:12 -07001015 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrc1));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001016}
1017
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018// Test that bitrate cannot be set for CBR codecs.
1019// Bitrate is ignored if it is higher than the fixed bitrate.
1020// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001021TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001022 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023
1024 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001025 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -07001026 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001027
1028 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001029 SetSendParameters(send_parameters_);
minyue7a973442016-10-20 03:27:12 -07001030 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001031
1032 send_parameters_.max_bandwidth_bps = 128;
1033 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
minyue7a973442016-10-20 03:27:12 -07001034 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035}
1036
skvlade0d46372016-04-07 22:59:22 -07001037// Test that the per-stream bitrate limit and the global
1038// bitrate limit both apply.
1039TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1040 EXPECT_TRUE(SetupSendStream());
1041
1042 // opus, default bitrate == 64000.
1043 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1044 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1045 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1046 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1047
1048 // CBR codecs allow both maximums to exceed the bitrate.
1049 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1050 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1051 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1053
1054 // CBR codecs don't allow per stream maximums to be too low.
1055 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1056 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1057}
1058
1059// Test that an attempt to set RtpParameters for a stream that does not exist
1060// fails.
1061TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1062 EXPECT_TRUE(SetupChannel());
1063 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001064 channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001065 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1066
1067 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001068 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001069}
1070
1071TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001072 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001073 // This test verifies that setting RtpParameters succeeds only if
1074 // the structure contains exactly one encoding.
1075 // TODO(skvlad): Update this test when we start supporting setting parameters
1076 // for each encoding individually.
1077
1078 EXPECT_TRUE(SetupSendStream());
deadbeeffb2aced2017-01-06 23:05:37 -08001079 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
skvlade0d46372016-04-07 22:59:22 -07001080 // Two or more encodings should result in failure.
1081 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001082 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001083 // Zero encodings should also fail.
1084 parameters.encodings.clear();
1085 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
1086}
1087
1088// Changing the SSRC through RtpParameters is not allowed.
1089TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1090 EXPECT_TRUE(SetupSendStream());
1091 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
1092 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
1093 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters));
skvlade0d46372016-04-07 22:59:22 -07001094}
1095
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001096// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1099 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001100 SetSend(true);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001101 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1102 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001103 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001104 ASSERT_EQ(1u, parameters.encodings.size());
1105 ASSERT_TRUE(parameters.encodings[0].active);
1106 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001107 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001108 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
1109
1110 // Now change it back to active and verify we resume sending.
1111 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters));
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001113 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
1114}
1115
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001116// Test that SetRtpSendParameters configures the correct encoding channel for
1117// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001118TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1119 SetupForMultiSendStream();
1120 // Create send streams.
1121 for (uint32_t ssrc : kSsrcs4) {
1122 EXPECT_TRUE(
1123 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1124 }
1125 // Configure one stream to be limited by the stream config, another to be
1126 // limited by the global max, and the third one with no per-stream limit
1127 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001128 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001129 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1130 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1131 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1132
1133 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1134 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1135 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1136
1137 // Remove the global cap; the streams should switch to their respective
1138 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001139 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001140 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1141 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1142 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1143}
1144
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001145// Test that GetRtpSendParameters returns the currently configured codecs.
1146TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147 EXPECT_TRUE(SetupSendStream());
1148 cricket::AudioSendParameters parameters;
1149 parameters.codecs.push_back(kIsacCodec);
1150 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001151 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001153 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1156 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157}
1158
deadbeefcb443432016-12-12 11:12:36 -08001159// Test that GetRtpSendParameters returns an SSRC.
1160TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1161 EXPECT_TRUE(SetupSendStream());
1162 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1);
1163 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1164 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1165}
1166
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001167// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001168TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001169 EXPECT_TRUE(SetupSendStream());
1170 cricket::AudioSendParameters parameters;
1171 parameters.codecs.push_back(kIsacCodec);
1172 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001173 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001174
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001175 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrc1);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176
1177 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001178 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001179
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001180 // ... And this shouldn't change the params returned by GetRtpSendParameters.
1181 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrc1);
1182 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrc1));
1183}
1184
1185// Test that GetRtpReceiveParameters returns the currently configured codecs.
1186TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1187 EXPECT_TRUE(SetupRecvStream());
1188 cricket::AudioRecvParameters parameters;
1189 parameters.codecs.push_back(kIsacCodec);
1190 parameters.codecs.push_back(kPcmuCodec);
1191 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1192
1193 webrtc::RtpParameters rtp_parameters =
1194 channel_->GetRtpReceiveParameters(kSsrc1);
1195 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1196 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1197 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1198}
1199
deadbeefcb443432016-12-12 11:12:36 -08001200// Test that GetRtpReceiveParameters returns an SSRC.
1201TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1202 EXPECT_TRUE(SetupRecvStream());
1203 webrtc::RtpParameters rtp_parameters =
1204 channel_->GetRtpReceiveParameters(kSsrc1);
1205 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1206 EXPECT_EQ(kSsrc1, rtp_parameters.encodings[0].ssrc);
1207}
1208
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209// Test that if we set/get parameters multiple times, we get the same results.
1210TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1211 EXPECT_TRUE(SetupRecvStream());
1212 cricket::AudioRecvParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
1215 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1216
1217 webrtc::RtpParameters initial_params =
1218 channel_->GetRtpReceiveParameters(kSsrc1);
1219
1220 // We should be able to set the params we just got.
1221 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrc1, initial_params));
1222
1223 // ... And this shouldn't change the params returned by
1224 // GetRtpReceiveParameters.
1225 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrc1);
1226 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrc1));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001227}
1228
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001229// Test that we apply codecs properly.
1230TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001231 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001232 cricket::AudioSendParameters parameters;
1233 parameters.codecs.push_back(kIsacCodec);
1234 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001235 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001236 parameters.codecs[0].id = 96;
1237 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001238 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001239 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001240 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
1241 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
1242 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1243 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1244 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1245 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1246 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1247 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001248 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001249}
1250
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001251// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1252// to apply.
1253TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001254 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001255 cricket::AudioSendParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001258 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001259 parameters.codecs[0].id = 96;
1260 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001261 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001262 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001263 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001264 // Calling SetSendCodec again with same codec which is already set.
1265 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001266 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001267 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001268}
1269
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001270// Verify that G722 is set with 16000 samples per second to WebRTC.
1271TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001272 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 cricket::AudioSendParameters parameters;
1274 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001275 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001276 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001277 EXPECT_STREQ("G722", gcodec.plname);
1278 EXPECT_EQ(1, gcodec.channels);
1279 EXPECT_EQ(16000, gcodec.plfreq);
1280}
1281
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001282// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kOpusCodec);
1287 parameters.codecs[0].bitrate = 0;
1288 parameters.codecs[0].clockrate = 50000;
1289 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290}
1291
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001292// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001294 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001295 cricket::AudioSendParameters parameters;
1296 parameters.codecs.push_back(kOpusCodec);
1297 parameters.codecs[0].bitrate = 0;
1298 parameters.codecs[0].channels = 0;
1299 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300}
1301
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001302// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001304 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001305 cricket::AudioSendParameters parameters;
1306 parameters.codecs.push_back(kOpusCodec);
1307 parameters.codecs[0].bitrate = 0;
1308 parameters.codecs[0].channels = 0;
1309 parameters.codecs[0].params["stereo"] = "1";
1310 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311}
1312
1313// Test that if channel is 1 for opus and there's no stereo, we fail.
1314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].channels = 1;
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
1323// Test that if channel is 1 for opus and stereo=0, we fail.
1324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001325 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 cricket::AudioSendParameters parameters;
1327 parameters.codecs.push_back(kOpusCodec);
1328 parameters.codecs[0].bitrate = 0;
1329 parameters.codecs[0].channels = 1;
1330 parameters.codecs[0].params["stereo"] = "0";
1331 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
1334// Test that if channel is 1 for opus and stereo=1, we fail.
1335TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001336 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001337 cricket::AudioSendParameters parameters;
1338 parameters.codecs.push_back(kOpusCodec);
1339 parameters.codecs[0].bitrate = 0;
1340 parameters.codecs[0].channels = 1;
1341 parameters.codecs[0].params["stereo"] = "1";
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
1345// Test that with bitrate=0 and no stereo,
1346// channels and bitrate are 1 and 32000.
1347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001353 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
1356// Test that with bitrate=0 and stereo=0,
1357// channels and bitrate are 1 and 32000.
1358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001364 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001365 CheckSendCodec(kSsrc1, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001368// Test that with bitrate=invalid and stereo=0,
1369// channels and bitrate are 1 and 32000.
1370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001375 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001376 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001378 CheckSendCodec(kSsrc1, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001379
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001381 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001382 CheckSendCodec(kSsrc1, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001383}
1384
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385// Test that with bitrate=0 and stereo=1,
1386// channels and bitrate are 2 and 64000.
1387TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kOpusCodec);
1391 parameters.codecs[0].bitrate = 0;
1392 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001394 CheckSendCodec(kSsrc1, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397// Test that with bitrate=invalid and stereo=1,
1398// channels and bitrate are 2 and 64000.
1399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001404 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001407 CheckSendCodec(kSsrc1, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001408
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001410 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001411 CheckSendCodec(kSsrc1, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001412}
1413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414// Test that with bitrate=N and stereo unset,
1415// channels and bitrate are 1 and N.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001422 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423 EXPECT_EQ(111, gcodec.pltype);
1424 EXPECT_EQ(96000, gcodec.rate);
1425 EXPECT_STREQ("opus", gcodec.plname);
1426 EXPECT_EQ(1, gcodec.channels);
1427 EXPECT_EQ(48000, gcodec.plfreq);
1428}
1429
1430// Test that with bitrate=N and stereo=0,
1431// channels and bitrate are 1 and N.
1432TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
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;
1437 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001439 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440}
1441
1442// Test that with bitrate=N and without any parameters,
1443// channels and bitrate are 1 and N.
1444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001449 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001450 CheckSendCodec(kSsrc1, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
1453// Test that with bitrate=N and stereo=1,
1454// channels and bitrate are 2 and N.
1455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 30000;
1460 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001462 CheckSendCodec(kSsrc1, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001465// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1466// Also test that the "maxaveragebitrate" can't be set to values outside the
1467// range of 6000 and 510000
1468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001473 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001474 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001475 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001476 EXPECT_EQ(6000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001477
1478 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001480 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001481 EXPECT_EQ(510000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001482
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001483 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001484 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001485 EXPECT_EQ(200000, GetCodecBitrate(kSsrc1));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001486}
1487
stefan13f1a0a2016-11-30 07:22:58 -08001488TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1489 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1490 200000);
1491}
1492
1493TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1494 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1495}
1496
1497TEST_F(WebRtcVoiceEngineTestFake,
1498 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1499 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1500}
1501
1502TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1503 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1504}
1505
1506TEST_F(WebRtcVoiceEngineTestFake,
1507 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1508 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1509 200000);
1510 send_parameters_.max_bandwidth_bps = 300000;
1511 SetSendParameters(send_parameters_);
1512 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1513 << "Setting max bitrate should keep previous min bitrate.";
1514 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1515 << "Setting max bitrate should not reset start bitrate.";
1516 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1517}
1518
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001519// Test that we can enable NACK with opus as caller.
1520TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001521 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 cricket::AudioSendParameters parameters;
1523 parameters.codecs.push_back(kOpusCodec);
1524 parameters.codecs[0].AddFeedbackParam(
1525 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1526 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001527 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001528 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001529 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001530}
1531
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001532// Test that we can enable NACK with opus as callee.
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001534 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].AddFeedbackParam(
1538 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1539 cricket::kParamValueEmpty));
solenberg8189b022016-06-14 12:13:00 -07001540 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001542 // NACK should be enabled even with no send stream.
solenberg8189b022016-06-14 12:13:00 -07001543 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001544
1545 EXPECT_TRUE(channel_->AddSendStream(
1546 cricket::StreamParams::CreateLegacy(kSsrc1)));
solenberg971cab02016-06-14 10:02:41 -07001547 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001548}
1549
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001550// Test that we can enable NACK on receive streams.
1551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001553 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 cricket::AudioSendParameters parameters;
1555 parameters.codecs.push_back(kOpusCodec);
1556 parameters.codecs[0].AddFeedbackParam(
1557 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1558 cricket::kParamValueEmpty));
solenberg971cab02016-06-14 10:02:41 -07001559 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001560 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001561 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001562 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001563 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
1566// Test that we can disable NACK.
1567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kOpusCodec);
1571 parameters.codecs[0].AddFeedbackParam(
1572 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1573 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001575 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 parameters.codecs.clear();
1578 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001579 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001580 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581}
1582
1583// Test that we can disable NACK on receive streams.
1584TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001585 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07001586 EXPECT_TRUE(AddRecvStream(kSsrc2));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001587 cricket::AudioSendParameters parameters;
1588 parameters.codecs.push_back(kOpusCodec);
1589 parameters.codecs[0].AddFeedbackParam(
1590 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1591 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001593 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001594 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 parameters.codecs.clear();
1597 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001598 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001599 EXPECT_EQ(0, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
solenberg8189b022016-06-14 12:13:00 -07001600 EXPECT_EQ(0, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601}
1602
1603// Test that NACK is enabled on a new receive stream.
1604TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001605 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters parameters;
1607 parameters.codecs.push_back(kIsacCodec);
1608 parameters.codecs.push_back(kCn16000Codec);
1609 parameters.codecs[0].AddFeedbackParam(
1610 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1611 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
solenberg971cab02016-06-14 10:02:41 -07001613 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrc1).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614
solenberg8189b022016-06-14 12:13:00 -07001615 EXPECT_TRUE(AddRecvStream(kSsrc2));
1616 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc2).rtp.nack.rtp_history_ms);
1617 EXPECT_TRUE(AddRecvStream(kSsrc3));
1618 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrc3).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619}
1620
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001621// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001622TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001623 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 cricket::AudioSendParameters parameters;
1625 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001627 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001628}
1629
1630// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001633 cricket::AudioSendParameters parameters;
1634 parameters.codecs.push_back(kOpusCodec);
1635 parameters.codecs[0].bitrate = 0;
1636 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001638 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001639}
1640
1641// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters parameters;
1645 parameters.codecs.push_back(kOpusCodec);
1646 parameters.codecs[0].bitrate = 0;
1647 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001649 EXPECT_TRUE(GetCodecFec(kSsrc1));
1650 CheckSendCodec(kSsrc1, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001651}
1652
1653// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001654TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001655 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001656 cricket::AudioSendParameters parameters;
1657 parameters.codecs.push_back(kOpusCodec);
1658 parameters.codecs[0].bitrate = 0;
1659 parameters.codecs[0].params["stereo"] = "1";
1660 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001661 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001662 EXPECT_TRUE(GetCodecFec(kSsrc1));
1663 CheckSendCodec(kSsrc1, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001664}
1665
1666// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001667TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001668 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 cricket::AudioSendParameters parameters;
1670 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001672 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001673}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001674
1675// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters parameters;
1679 parameters.codecs.push_back(kIsacCodec);
1680 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001682 EXPECT_FALSE(GetCodecFec(kSsrc1));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001683}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001684
1685// Test that Opus FEC status can be changed.
1686TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 cricket::AudioSendParameters parameters;
1689 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001691 EXPECT_FALSE(GetCodecFec(kSsrc1));
1692
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001695 EXPECT_TRUE(GetCodecFec(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001696}
1697
stefanba4c0e42016-02-04 04:12:24 -08001698TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001700 cricket::AudioSendParameters send_parameters;
1701 send_parameters.codecs.push_back(kOpusCodec);
1702 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001704
1705 cricket::AudioRecvParameters recv_parameters;
1706 recv_parameters.codecs.push_back(kIsacCodec);
1707 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg8189b022016-06-14 12:13:00 -07001708 EXPECT_TRUE(AddRecvStream(kSsrc1));
stefanba4c0e42016-02-04 04:12:24 -08001709 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1710 EXPECT_FALSE(
1711 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1712
ossudedfd282016-06-14 07:12:39 -07001713 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001715 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr);
1716 EXPECT_TRUE(
1717 call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc);
1718}
1719
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001720// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1721TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001723 cricket::AudioSendParameters parameters;
1724 parameters.codecs.push_back(kOpusCodec);
1725 parameters.codecs[0].bitrate = 0;
1726 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001728 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
1729 EXPECT_EQ(12000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001730
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001733 EXPECT_EQ(24000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001734}
1735
1736// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1737TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001738 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters parameters;
1740 parameters.codecs.push_back(kOpusCodec);
1741 parameters.codecs[0].bitrate = 0;
1742 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001744 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrc1));
1745 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001749 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001750}
1751
1752// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1753TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001754 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001755 cricket::AudioSendParameters parameters;
1756 parameters.codecs.push_back(kOpusCodec);
1757 parameters.codecs[0].bitrate = 0;
1758 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001760 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrc1));
1761 EXPECT_EQ(20000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001762
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001763 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001765 EXPECT_EQ(40000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001766}
1767
1768// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1769TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001770 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 cricket::AudioSendParameters parameters;
1772 parameters.codecs.push_back(kOpusCodec);
1773 parameters.codecs[0].bitrate = 0;
1774 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001776 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrc1));
1777 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001778
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001782}
1783
1784// Test 24000 < maxplaybackrate triggers Opus full band mode.
1785TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001786 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 cricket::AudioSendParameters parameters;
1788 parameters.codecs.push_back(kOpusCodec);
1789 parameters.codecs[0].bitrate = 0;
1790 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrc1));
1793 EXPECT_EQ(32000, GetCodecBitrate(kSsrc1));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001794
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001796 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001797 EXPECT_EQ(64000, GetCodecBitrate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001798}
1799
1800// Test Opus that without maxplaybackrate, default playback rate is used.
1801TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001802 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 cricket::AudioSendParameters parameters;
1804 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001805 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001806 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001807}
1808
1809// Test the with non-Opus, maxplaybackrate has no effect.
1810TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
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(kIsacCodec);
1814 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001817}
1818
1819// Test maxplaybackrate can be set on two streams.
1820TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
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);
solenberg059fb442016-10-26 05:12:24 -07001824 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001825 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001826
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001829 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc1));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001830
1831 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
minyue7a973442016-10-20 03:27:12 -07001832 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrc2));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001833}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001834
Minyue Li7100dcd2015-03-27 05:05:59 +01001835// Test that with usedtx=0, Opus DTX is off.
1836TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001837 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 cricket::AudioSendParameters parameters;
1839 parameters.codecs.push_back(kOpusCodec);
1840 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001841 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001842 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001843}
1844
1845// Test that with usedtx=1, Opus DTX is on.
1846TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001847 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 cricket::AudioSendParameters parameters;
1849 parameters.codecs.push_back(kOpusCodec);
1850 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001852 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001853}
1854
1855// Test that usedtx=1 works with stereo Opus.
1856TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
1859 parameters.codecs.push_back(kOpusCodec);
1860 parameters.codecs[0].params["usedtx"] = "1";
1861 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001863 EXPECT_TRUE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001864}
1865
1866// Test that usedtx=1 does not work with non Opus.
1867TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001868 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 cricket::AudioSendParameters parameters;
1870 parameters.codecs.push_back(kIsacCodec);
1871 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001873 EXPECT_FALSE(GetOpusDtx(kSsrc1));
Minyue Li7100dcd2015-03-27 05:05:59 +01001874}
1875
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001876// Test that we can switch back and forth between Opus and ISAC with CN.
1877TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001878 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001879
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 cricket::AudioSendParameters opus_parameters;
1881 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001882 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001883 {
1884 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1885 EXPECT_EQ(111, gcodec.pltype);
1886 EXPECT_STREQ("opus", gcodec.plname);
1887 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001888
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 cricket::AudioSendParameters isac_parameters;
1890 isac_parameters.codecs.push_back(kIsacCodec);
1891 isac_parameters.codecs.push_back(kCn16000Codec);
1892 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001894 {
1895 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1896 EXPECT_EQ(103, gcodec.pltype);
1897 EXPECT_STREQ("ISAC", gcodec.plname);
1898 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001901 {
1902 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1903 EXPECT_EQ(111, gcodec.pltype);
1904 EXPECT_STREQ("opus", gcodec.plname);
1905 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001906}
1907
1908// Test that we handle various ways of specifying bitrate.
1909TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001910 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 cricket::AudioSendParameters parameters;
1912 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001913 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001914 {
1915 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1916 EXPECT_EQ(103, gcodec.pltype);
1917 EXPECT_STREQ("ISAC", gcodec.plname);
1918 EXPECT_EQ(32000, gcodec.rate);
1919 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 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(103, gcodec.pltype);
1926 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001927 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001928 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001930 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001931 {
1932 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1933 EXPECT_EQ(103, gcodec.pltype);
1934 EXPECT_STREQ("ISAC", gcodec.plname);
1935 EXPECT_EQ(28000, gcodec.rate);
1936 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001938 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001939 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001940 {
1941 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1942 EXPECT_EQ(0, gcodec.pltype);
1943 EXPECT_STREQ("PCMU", gcodec.plname);
1944 EXPECT_EQ(64000, gcodec.rate);
1945 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001946
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001948 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001949 {
1950 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1951 EXPECT_EQ(0, gcodec.pltype);
1952 EXPECT_STREQ("PCMU", gcodec.plname);
1953 EXPECT_EQ(64000, gcodec.rate);
1954 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001956 parameters.codecs[0] = kOpusCodec;
1957 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001958 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001959 {
1960 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
1961 EXPECT_EQ(111, gcodec.pltype);
1962 EXPECT_STREQ("opus", gcodec.plname);
1963 EXPECT_EQ(32000, gcodec.rate);
1964 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965}
1966
Brave Yao5225dd82015-03-26 07:39:19 +08001967// Test that we could set packet size specified in kCodecParamPTime.
1968TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001969 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 cricket::AudioSendParameters parameters;
1971 parameters.codecs.push_back(kOpusCodec);
1972 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001974 EXPECT_EQ(1920, GetCodecPacSize(kSsrc1)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001975
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001978 EXPECT_EQ(480, GetCodecPacSize(kSsrc1)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001979
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 EXPECT_EQ(2880, GetCodecPacSize(kSsrc1)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001983
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001984 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1985 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001987 EXPECT_EQ(480, GetCodecPacSize(
1988 kSsrc1)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001989
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1991 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001993 EXPECT_EQ(640, GetCodecPacSize(
1994 kSsrc1)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001995}
1996
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001997// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001999 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002000 cricket::AudioSendParameters parameters;
2001 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002002}
2003
2004// Test that we can set send codecs even with telephone-event codec as the first
2005// one on the list.
2006TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002007 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002008 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002009 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 parameters.codecs.push_back(kIsacCodec);
2011 parameters.codecs.push_back(kPcmuCodec);
2012 parameters.codecs[0].id = 98; // DTMF
2013 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002014 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002015 const auto& gcodec = GetSendStreamConfig(kSsrc1).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002016 EXPECT_EQ(96, gcodec.pltype);
2017 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002018 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002019}
2020
solenberg31642aa2016-03-14 08:00:37 -07002021// Test that payload type range is limited for telephone-event codec.
2022TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002023 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002024 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002025 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002026 parameters.codecs.push_back(kIsacCodec);
2027 parameters.codecs[0].id = 0; // DTMF
2028 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002029 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002030 EXPECT_TRUE(channel_->CanInsertDtmf());
2031 parameters.codecs[0].id = 128; // DTMF
2032 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2033 EXPECT_FALSE(channel_->CanInsertDtmf());
2034 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002035 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002036 EXPECT_TRUE(channel_->CanInsertDtmf());
2037 parameters.codecs[0].id = -1; // DTMF
2038 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2039 EXPECT_FALSE(channel_->CanInsertDtmf());
2040}
2041
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002042// Test that we can set send codecs even with CN codec as the first
2043// one on the list.
2044TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002045 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002046 cricket::AudioSendParameters parameters;
2047 parameters.codecs.push_back(kCn16000Codec);
2048 parameters.codecs.push_back(kIsacCodec);
2049 parameters.codecs.push_back(kPcmuCodec);
2050 parameters.codecs[0].id = 98; // wideband CN
2051 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002052 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002053 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2054 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2055 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2056 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2057 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002058}
2059
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002060// Test that we set VAD and DTMF types correctly as caller.
2061TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002062 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002063 cricket::AudioSendParameters parameters;
2064 parameters.codecs.push_back(kIsacCodec);
2065 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002066 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002067 parameters.codecs.push_back(kCn16000Codec);
2068 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002069 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002070 parameters.codecs[0].id = 96;
2071 parameters.codecs[2].id = 97; // wideband CN
2072 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002073 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002074 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2075 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2076 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2077 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2078 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2079 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2080 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002081 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002082}
2083
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002084// Test that we set VAD and DTMF types correctly as callee.
2085TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002086 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002087 cricket::AudioSendParameters parameters;
2088 parameters.codecs.push_back(kIsacCodec);
2089 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002090 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002091 parameters.codecs.push_back(kCn16000Codec);
2092 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002093 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002094 parameters.codecs[0].id = 96;
2095 parameters.codecs[2].id = 97; // wideband CN
2096 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002097 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002098 EXPECT_TRUE(channel_->AddSendStream(
2099 cricket::StreamParams::CreateLegacy(kSsrc1)));
2100
minyue7a973442016-10-20 03:27:12 -07002101 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2102 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2103 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2104 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2105 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2106 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2107 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002108 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002109}
2110
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111// Test that we only apply VAD if we have a CN codec that matches the
2112// send codec clockrate.
2113TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002114 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002115 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002116 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002117 parameters.codecs.push_back(kIsacCodec);
2118 parameters.codecs.push_back(kCn16000Codec);
2119 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002121 {
2122 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2123 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2124 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2125 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2126 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2127 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2128 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002129 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002130 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002131 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002132 {
2133 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2134 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2135 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2136 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002138 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002139 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002140 {
2141 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2142 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2143 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2144 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2145 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2146 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2147 }
Brave Yao5225dd82015-03-26 07:39:19 +08002148 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002149 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002150 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002151 {
2152 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2153 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2154 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2155 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002156}
2157
2158// Test that we perform case-insensitive matching of codec names.
2159TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002160 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 cricket::AudioSendParameters parameters;
2162 parameters.codecs.push_back(kIsacCodec);
2163 parameters.codecs.push_back(kPcmuCodec);
2164 parameters.codecs.push_back(kCn16000Codec);
2165 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002166 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 parameters.codecs[0].name = "iSaC";
2168 parameters.codecs[0].id = 96;
2169 parameters.codecs[2].id = 97; // wideband CN
2170 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002171 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002172 const auto& send_codec_spec = GetSendStreamConfig(kSsrc1).send_codec_spec;
2173 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2174 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2175 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2176 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2177 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2178 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002179 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180}
2181
stefanba4c0e42016-02-04 04:12:24 -08002182class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2183 public:
2184 WebRtcVoiceEngineWithSendSideBweTest()
2185 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2186};
2187
2188TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2189 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002190 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002191 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002192 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2193 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2194 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002195 extension.id);
2196 return;
2197 }
2198 }
2199 FAIL() << "Transport sequence number extension not in header-extension list.";
2200}
2201
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002202// Test support for audio level header extension.
2203TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002204 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002205}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002206TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002207 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002208}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002209
solenbergd4adce42016-11-17 06:26:52 -08002210// Test support for transport sequence number header extension.
2211TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2212 TestSetSendRtpHeaderExtensions(
2213 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002214}
solenbergd4adce42016-11-17 06:26:52 -08002215TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2216 TestSetRecvRtpHeaderExtensions(
2217 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218}
2219
solenberg1ac56142015-10-13 03:58:19 -07002220// Test that we can create a channel and start sending on it.
2221TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002222 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002223 SetSendParameters(send_parameters_);
2224 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002225 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002226 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002227 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2228}
2229
2230// Test that a channel will send if and only if it has a source and is enabled
2231// for sending.
2232TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002233 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002234 SetSendParameters(send_parameters_);
2235 SetAudioSend(kSsrc1, true, nullptr);
2236 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002237 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002238 SetAudioSend(kSsrc1, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002239 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002240 SetAudioSend(kSsrc1, true, nullptr);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002241 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002242}
2243
solenberg94218532016-06-16 10:53:22 -07002244// Test that a channel is muted/unmuted.
2245TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2246 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002247 SetSendParameters(send_parameters_);
solenberg94218532016-06-16 10:53:22 -07002248 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002249 SetAudioSend(kSsrc1, true, nullptr);
solenberg94218532016-06-16 10:53:22 -07002250 EXPECT_FALSE(GetSendStream(kSsrc1).muted());
solenberg059fb442016-10-26 05:12:24 -07002251 SetAudioSend(kSsrc1, false, nullptr);
solenberg94218532016-06-16 10:53:22 -07002252 EXPECT_TRUE(GetSendStream(kSsrc1).muted());
2253}
2254
solenberg6d6e7c52016-04-13 09:07:30 -07002255// Test that SetSendParameters() does not alter a stream's send state.
2256TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2257 EXPECT_TRUE(SetupSendStream());
2258 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2259
2260 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002261 SetSend(true);
solenberg6d6e7c52016-04-13 09:07:30 -07002262 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2263
2264 // Changing RTP header extensions will recreate the AudioSendStream.
2265 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002266 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002267 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002268 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
2269
2270 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002271 SetSend(false);
solenberg6d6e7c52016-04-13 09:07:30 -07002272 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2273
2274 // Changing RTP header extensions will recreate the AudioSendStream.
2275 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002276 SetSendParameters(send_parameters_);
solenberg6d6e7c52016-04-13 09:07:30 -07002277 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
2278}
2279
solenberg1ac56142015-10-13 03:58:19 -07002280// Test that we can create a channel and start playing out on it.
2281TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002282 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002283 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002284 channel_->SetPlayout(true);
2285 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
2286 channel_->SetPlayout(false);
2287 EXPECT_FALSE(GetRecvStream(kSsrc1).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288}
2289
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002290// Test that we can add and remove send streams.
2291TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2292 SetupForMultiSendStream();
2293
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002294 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002295 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002296
solenbergc96df772015-10-21 13:01:53 -07002297 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002298 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002299 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002300 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002301 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002302 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002303 }
tfarina5237aaf2015-11-10 23:44:30 -08002304 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305
solenbergc96df772015-10-21 13:01:53 -07002306 // Delete the send streams.
2307 for (uint32_t ssrc : kSsrcs4) {
2308 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002309 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002310 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002311 }
solenbergc96df772015-10-21 13:01:53 -07002312 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002313}
2314
2315// Test SetSendCodecs correctly configure the codecs in all send streams.
2316TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2317 SetupForMultiSendStream();
2318
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002319 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002320 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002321 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002322 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 }
2324
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002325 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002326 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002327 parameters.codecs.push_back(kIsacCodec);
2328 parameters.codecs.push_back(kCn16000Codec);
2329 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002330 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002331
2332 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002333 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002334 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2335 const auto& send_codec_spec =
2336 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2337 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2338 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2339 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2340 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2341 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342 }
2343
minyue7a973442016-10-20 03:27:12 -07002344 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002345 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002346 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002347 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002348 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2349 const auto& send_codec_spec =
2350 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2351 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2352 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2353 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2354 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 }
2356}
2357
2358// Test we can SetSend on all send streams correctly.
2359TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2360 SetupForMultiSendStream();
2361
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002362 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002363 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002364 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002365 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002366 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002367 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002368 }
2369
2370 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002371 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002372 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002373 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002374 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002375 }
2376
2377 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002378 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002379 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002380 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002381 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 }
2383}
2384
2385// Test we can set the correct statistics on all send streams.
2386TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2387 SetupForMultiSendStream();
2388
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002389 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002390 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002392 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002393 }
solenberg85a04962015-10-27 03:35:21 -07002394
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002395 // Create a receive stream to check that none of the send streams end up in
2396 // the receive stream stats.
solenberg8189b022016-06-14 12:13:00 -07002397 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg971cab02016-06-14 10:02:41 -07002398
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002399 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002400 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002401 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002402 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002403
solenberg85a04962015-10-27 03:35:21 -07002404 // Check stats for the added streams.
2405 {
2406 cricket::VoiceMediaInfo info;
2407 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002408
solenberg85a04962015-10-27 03:35:21 -07002409 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002410 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002411 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002412 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002413 }
hbos1acfbd22016-11-17 23:43:29 -08002414 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002415
2416 // We have added one receive stream. We should see empty stats.
2417 EXPECT_EQ(info.receivers.size(), 1u);
2418 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002419 }
solenberg1ac56142015-10-13 03:58:19 -07002420
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002421 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002422 {
2423 cricket::VoiceMediaInfo info;
2424 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2425 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002426 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002427 EXPECT_EQ(0u, info.receivers.size());
2428 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002429
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002430 // Deliver a new packet - a default receive stream should be created and we
2431 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002432 {
2433 cricket::VoiceMediaInfo info;
2434 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2435 SetAudioReceiveStreamStats();
2436 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002437 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002438 EXPECT_EQ(1u, info.receivers.size());
2439 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002440 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002441 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002442}
2443
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002444// Test that we can add and remove receive streams, and do proper send/playout.
2445// We can receive on multiple streams while sending one stream.
2446TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448
solenberg1ac56142015-10-13 03:58:19 -07002449 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002450 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002451 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452
solenberg1ac56142015-10-13 03:58:19 -07002453 // Adding another stream should enable playout on the new stream only.
solenberg8189b022016-06-14 12:13:00 -07002454 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002455 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002456 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457
solenberg1ac56142015-10-13 03:58:19 -07002458 // Make sure only the new stream is played out.
aleloi84ef6152016-08-04 05:28:21 -07002459 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460
2461 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg8189b022016-06-14 12:13:00 -07002462 EXPECT_TRUE(AddRecvStream(kSsrc3));
aleloi84ef6152016-08-04 05:28:21 -07002463 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2464 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465
2466 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002467 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002468 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469
2470 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002471 channel_->SetPlayout(false);
2472 EXPECT_FALSE(GetRecvStream(kSsrc2).started());
2473 EXPECT_FALSE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474
aleloi84ef6152016-08-04 05:28:21 -07002475 // Restart playout and make sure recv streams are played out.
2476 channel_->SetPlayout(true);
2477 EXPECT_TRUE(GetRecvStream(kSsrc2).started());
2478 EXPECT_TRUE(GetRecvStream(kSsrc3).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479
aleloi84ef6152016-08-04 05:28:21 -07002480 // Now remove the recv streams.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2482 EXPECT_TRUE(channel_->RemoveRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483}
2484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002486// and start sending on it.
2487TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002489 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2490 EXPECT_CALL(apm_gc_,
2491 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002492 SetSendParameters(send_parameters_);
2493 SetSend(true);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002494 EXPECT_TRUE(GetSendStream(kSsrc1).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002495 SetSend(false);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002496 EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497}
2498
wu@webrtc.org97077a32013-10-25 21:18:33 +00002499TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002500 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002501 EXPECT_CALL(adm_,
2502 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002503 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2504 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002505 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2506 send_parameters_.options.tx_agc_digital_compression_gain =
2507 rtc::Optional<uint16_t>(9);
2508 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2509 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002510 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2511 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2512 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002513 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002514
2515 // Check interaction with adjust_agc_delta. Both should be respected, for
2516 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002517 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002518 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002519 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002520}
2521
wu@webrtc.org97077a32013-10-25 21:18:33 +00002522TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002523 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002524 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2525 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002526 send_parameters_.options.recording_sample_rate =
2527 rtc::Optional<uint32_t>(48000);
2528 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002529 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002530}
2531
minyue6b825df2016-10-31 04:08:32 -07002532TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
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}
2541
2542TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2543 EXPECT_TRUE(SetupSendStream());
2544 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2545 send_parameters_.options.audio_network_adaptor_config =
2546 rtc::Optional<std::string>("1234");
2547 SetSendParameters(send_parameters_);
2548 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2549 GetAudioNetworkAdaptorConfig(kSsrc1));
2550 const int initial_num = call_.GetNumCreatedSendStreams();
2551 cricket::AudioOptions options;
2552 options.audio_network_adaptor = rtc::Optional<bool>(false);
2553 SetAudioSend(kSsrc1, true, nullptr, &options);
2554 // AudioSendStream expected to be recreated.
2555 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
2556 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrc1));
2557}
2558
2559TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2560 EXPECT_TRUE(SetupSendStream());
2561 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2562 send_parameters_.options.audio_network_adaptor_config =
2563 rtc::Optional<std::string>("1234");
2564 SetSendParameters(send_parameters_);
2565 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2566 GetAudioNetworkAdaptorConfig(kSsrc1));
2567 const int initial_num = call_.GetNumCreatedSendStreams();
2568 cricket::AudioOptions options;
2569 options.audio_network_adaptor = rtc::Optional<bool>();
2570 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2571 // adaptor.
2572 SetAudioSend(kSsrc1, true, nullptr, &options);
2573 // AudioSendStream not expected to be recreated.
2574 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2575 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
2576 GetAudioNetworkAdaptorConfig(kSsrc1));
2577}
2578
michaelt6672b262017-01-11 10:17:59 -08002579class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2580 : public WebRtcVoiceEngineTestFake {
2581 public:
2582 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2583 : WebRtcVoiceEngineTestFake(
2584 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2585 "Enabled/") {}
2586};
2587
2588TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2589 EXPECT_TRUE(SetupSendStream());
2590 cricket::AudioSendParameters parameters;
2591 parameters.codecs.push_back(kOpusCodec);
2592 SetSendParameters(parameters);
2593 const int initial_num = call_.GetNumCreatedSendStreams();
2594 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2595
2596 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2597 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002598 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2599 constexpr int kMinOverheadBps =
2600 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002601 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2602
2603 constexpr int kOpusMinBitrateBps = 6000;
2604 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
2605 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2606 constexpr int kOpusBitrateFbBps = 32000;
2607 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
2608 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2609
2610 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2611 parameters.options.audio_network_adaptor_config =
2612 rtc::Optional<std::string>("1234");
2613 SetSendParameters(parameters);
2614
ossu11bfc532017-02-16 05:37:06 -08002615 constexpr int kMinOverheadWithAnaBps =
2616 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002617 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2618
2619 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
2620 GetSendStreamConfig(kSsrc1).min_bitrate_bps);
2621
2622 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
2623 GetSendStreamConfig(kSsrc1).max_bitrate_bps);
2624}
2625
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002627// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002628TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002629 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002630 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631}
2632
2633TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2634 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002635 EXPECT_TRUE(SetupSendStream());
solenbergff976312016-03-30 23:28:51 -07002636 // SetupSendStream adds a send stream with kSsrc1, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002637 // stream has to use a different SSRC.
solenberg8189b022016-06-14 12:13:00 -07002638 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg059fb442016-10-26 05:12:24 -07002639 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002640 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002641 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642
solenberg85a04962015-10-27 03:35:21 -07002643 // Check stats for the added streams.
2644 {
2645 cricket::VoiceMediaInfo info;
2646 EXPECT_EQ(true, channel_->GetStats(&info));
2647
2648 // We have added one send stream. We should see the stats we've set.
2649 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002650 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002651 // We have added one receive stream. We should see empty stats.
2652 EXPECT_EQ(info.receivers.size(), 1u);
2653 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2654 }
solenberg1ac56142015-10-13 03:58:19 -07002655
solenberg566ef242015-11-06 15:34:49 -08002656 // Start sending - this affects some reported stats.
2657 {
2658 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002659 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002660 EXPECT_EQ(true, channel_->GetStats(&info));
2661 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002662 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002663 }
2664
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002665 // Remove the kSsrc2 stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002666 {
2667 cricket::VoiceMediaInfo info;
2668 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2669 EXPECT_EQ(true, channel_->GetStats(&info));
2670 EXPECT_EQ(1u, info.senders.size());
2671 EXPECT_EQ(0u, info.receivers.size());
2672 }
solenberg1ac56142015-10-13 03:58:19 -07002673
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002674 // Deliver a new packet - a default receive stream should be created and we
2675 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002676 {
2677 cricket::VoiceMediaInfo info;
2678 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2679 SetAudioReceiveStreamStats();
2680 EXPECT_EQ(true, channel_->GetStats(&info));
2681 EXPECT_EQ(1u, info.senders.size());
2682 EXPECT_EQ(1u, info.receivers.size());
2683 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002684 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002685 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002686}
2687
2688// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002689// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002691 EXPECT_TRUE(SetupSendStream());
solenberg3a941542015-11-16 07:34:50 -08002692 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
solenberg8189b022016-06-14 12:13:00 -07002693 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg7add0582015-11-20 09:59:34 -08002694 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002695}
2696
2697// Test that the local SSRC is the same on sending and receiving channels if the
2698// receive channel is created before the send channel.
2699TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002700 EXPECT_TRUE(SetupChannel());
solenberg4a0f7b52016-06-16 13:07:33 -07002701 EXPECT_TRUE(AddRecvStream(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002702 EXPECT_TRUE(channel_->AddSendStream(
solenberg4a0f7b52016-06-16 13:07:33 -07002703 cricket::StreamParams::CreateLegacy(kSsrc1)));
2704 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2705 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002706}
2707
2708// Test that we can properly receive packets.
2709TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002710 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002711 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002712 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002713
2714 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2715 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716}
2717
2718// Test that we can properly receive packets on multiple streams.
2719TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002720 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002721 const uint32_t ssrc1 = 1;
2722 const uint32_t ssrc2 = 2;
2723 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002724 EXPECT_TRUE(AddRecvStream(ssrc1));
2725 EXPECT_TRUE(AddRecvStream(ssrc2));
2726 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002728 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002729 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002731 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732 }
mflodman3d7db262016-04-29 00:57:13 -07002733
2734 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2735 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2736 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2737
2738 EXPECT_EQ(s1.received_packets(), 0);
2739 EXPECT_EQ(s2.received_packets(), 0);
2740 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002741
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002743 EXPECT_EQ(s1.received_packets(), 0);
2744 EXPECT_EQ(s2.received_packets(), 0);
2745 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002746
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002748 EXPECT_EQ(s1.received_packets(), 1);
2749 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2750 EXPECT_EQ(s2.received_packets(), 0);
2751 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002752
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002754 EXPECT_EQ(s1.received_packets(), 1);
2755 EXPECT_EQ(s2.received_packets(), 1);
2756 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2757 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002758
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002760 EXPECT_EQ(s1.received_packets(), 1);
2761 EXPECT_EQ(s2.received_packets(), 1);
2762 EXPECT_EQ(s3.received_packets(), 1);
2763 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002764
mflodman3d7db262016-04-29 00:57:13 -07002765 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2766 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2767 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768}
2769
solenberg7e63ef02015-11-20 00:19:43 -08002770// Test that receiving on an unsignalled stream works (default channel will be
2771// created).
2772TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
solenbergff976312016-03-30 23:28:51 -07002773 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002774 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2775
solenberg7e63ef02015-11-20 00:19:43 -08002776 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002777
2778 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2779 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2780 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002781}
2782
2783// Test that receiving on an unsignalled stream works (default channel will be
2784// created), and that packets will be forwarded to the default channel
2785// regardless of their SSRCs.
2786TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
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
mflodman3d7db262016-04-29 00:57:13 -07002791 // Note that ssrc = 0 is not supported.
2792 uint32_t ssrc = 1;
2793 for (; ssrc < 10; ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002794 rtc::SetBE32(&packet[8], ssrc);
2795 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002796
2797 // Verify we only have one default stream.
2798 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2799 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2800 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002801 }
mflodman3d7db262016-04-29 00:57:13 -07002802
2803 // Sending the same ssrc again should not create a new stream.
2804 --ssrc;
2805 DeliverPacket(packet, sizeof(packet));
2806 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2807 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2808 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002809}
2810
2811// Test that a default channel is created even after a signalled stream has been
2812// added, and that this stream will get any packets for unknown SSRCs.
2813TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
solenbergff976312016-03-30 23:28:51 -07002814 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002815 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002816 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2817
2818 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002819 const uint32_t signaled_ssrc = 1;
2820 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002821 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002822 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002823 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2824 packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002825
2826 // Note that the first unknown SSRC cannot be 0, because we only support
2827 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002828 const uint32_t unsignaled_ssrc = 7011;
2829 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002830 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002831 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2832 packet, sizeof(packet)));
2833 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2834
2835 DeliverPacket(packet, sizeof(packet));
2836 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2837
2838 rtc::SetBE32(&packet[8], signaled_ssrc);
2839 DeliverPacket(packet, sizeof(packet));
2840 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2841 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002842}
2843
solenberg4904fb62017-02-17 12:01:14 -08002844// Two tests to verify that adding a receive stream with the same SSRC as a
2845// previously added unsignaled stream will only recreate underlying stream
2846// objects if the stream parameters have changed.
2847TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2848 EXPECT_TRUE(SetupChannel());
2849
2850 // Spawn unsignaled stream with SSRC=1.
2851 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2852 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2853 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2854 sizeof(kPcmuFrame)));
2855
2856 // Verify that the underlying stream object in Call is not recreated when a
2857 // stream with SSRC=1 is added.
2858 const auto& streams = call_.GetAudioReceiveStreams();
2859 EXPECT_EQ(1, streams.size());
2860 int audio_receive_stream_id = streams.front()->id();
2861 EXPECT_TRUE(AddRecvStream(1));
2862 EXPECT_EQ(1, streams.size());
2863 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2864}
2865
2866TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2867 EXPECT_TRUE(SetupChannel());
2868
2869 // Spawn unsignaled stream with SSRC=1.
2870 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2871 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2872 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2873 sizeof(kPcmuFrame)));
2874
2875 // Verify that the underlying stream object in Call *is* recreated when a
2876 // stream with SSRC=1 is added, and which has changed stream parameters.
2877 const auto& streams = call_.GetAudioReceiveStreams();
2878 EXPECT_EQ(1, streams.size());
2879 int audio_receive_stream_id = streams.front()->id();
2880 cricket::StreamParams stream_params;
2881 stream_params.ssrcs.push_back(1);
2882 stream_params.sync_label = "sync_label";
2883 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2884 EXPECT_EQ(1, streams.size());
2885 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2886}
2887
solenberg0a617e22015-10-20 15:49:38 -07002888// Test that we properly handle failures to add a receive stream.
2889TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002890 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002892 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893}
2894
solenberg0a617e22015-10-20 15:49:38 -07002895// Test that we properly handle failures to add a send stream.
2896TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002897 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002898 voe_.set_fail_create_channel(true);
2899 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2900}
2901
solenberg1ac56142015-10-13 03:58:19 -07002902// Test that AddRecvStream creates new stream.
2903TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002904 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002906 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002907 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908}
2909
2910// Test that after adding a recv stream, we do not decode more codecs than
2911// those previously passed into SetRecvCodecs.
2912TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002913 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002914 cricket::AudioRecvParameters parameters;
2915 parameters.codecs.push_back(kIsacCodec);
2916 parameters.codecs.push_back(kPcmuCodec);
2917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg8189b022016-06-14 12:13:00 -07002918 EXPECT_TRUE(AddRecvStream(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002919 int channel_num2 = voe_.GetLastChannel();
2920 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002921 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002922 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002923 gcodec.channels = 2;
2924 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2925}
2926
2927// Test that we properly clean up any streams that were added, even if
2928// not explicitly removed.
2929TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002930 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002931 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002932 EXPECT_TRUE(AddRecvStream(1));
2933 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002934 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2935 delete channel_;
2936 channel_ = NULL;
2937 EXPECT_EQ(0, voe_.GetNumChannels());
2938}
2939
wu@webrtc.org78187522013-10-07 23:32:02 +00002940TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002941 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002942 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002943}
2944
2945TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002946 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002947 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002948 // Manually delete channel to simulate a failure.
2949 int channel = voe_.GetLastChannel();
2950 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2951 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002952 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002953 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002954 EXPECT_NE(channel, new_channel);
2955 // The last created channel is deleted too.
2956 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002957}
2958
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002959// Test the InsertDtmf on default send stream as caller.
2960TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002961 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962}
2963
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002964// Test the InsertDtmf on default send stream as callee
2965TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002966 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002967}
2968
2969// Test the InsertDtmf on specified send stream as caller.
2970TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002971 TestInsertDtmf(kSsrc1, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002972}
2973
2974// Test the InsertDtmf on specified send stream as callee.
2975TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002976 TestInsertDtmf(kSsrc1, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977}
2978
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002980 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002981 EXPECT_CALL(adm_,
2982 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2983 EXPECT_CALL(adm_,
2984 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2985 EXPECT_CALL(adm_,
2986 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002987
solenberg246b8172015-12-08 09:50:23 -08002988 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2989 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002990
solenberg246b8172015-12-08 09:50:23 -08002991 // Nothing set in AudioOptions, so everything should be as default.
2992 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002993 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002994 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002995 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2996 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997
2998 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002999 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3000 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003001 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003002 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003
3004 // Turn echo cancellation back on, with settings, and make sure
3005 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003006 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3007 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003008 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003009 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003011 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3012 // control.
solenberg76377c52017-02-21 00:54:31 -08003013 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3014 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003015 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003016 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003017
3018 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003019 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3020 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003021 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3022 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3023 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003024 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003025
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003026 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003027 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3028 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003029 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003030 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003031
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003033 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3034 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3035 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3036 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003037 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003038 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003039
3040 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003041 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3042 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3043 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3044 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003045 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3046 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003047 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048
3049 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003050 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3051 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3052 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3053 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3054 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3055 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3056 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003057 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3058 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3059 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3060 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003061 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003062 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063
solenberg1ac56142015-10-13 03:58:19 -07003064 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003065 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3066 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3067 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3068 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3069 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3070 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3071 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003072 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003073}
3074
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003076 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003077 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003078 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003079 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003080 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003081 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003082 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003083 EXPECT_CALL(adm_,
3084 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3085 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3086 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3087 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3088 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003089
kwiberg686a8ef2016-02-26 03:00:35 -08003090 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003091 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003092 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003093 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003094 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003095 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003096
3097 // Have to add a stream to make SetSend work.
3098 cricket::StreamParams stream1;
3099 stream1.ssrcs.push_back(1);
3100 channel1->AddSendStream(stream1);
3101 cricket::StreamParams stream2;
3102 stream2.ssrcs.push_back(2);
3103 channel2->AddSendStream(stream2);
3104
3105 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003106 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003107 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3108 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3109 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003110 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3111 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3112 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3113 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3114 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003115 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003116 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003117 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003118 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003119
3120 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003121 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003122 parameters_options_no_ns.options.noise_suppression =
3123 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003124 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3125 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3126 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3127 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3128 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003129 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003130 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003131 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3132 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3133 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003134 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003135
3136 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003137 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003138 parameters_options_no_agc.options.auto_gain_control =
3139 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003140 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3141 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3142 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3143 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3144 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003145 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003146 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3147 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3148 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003149 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003150
solenberg76377c52017-02-21 00:54:31 -08003151 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3152 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3153 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3154 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3155 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003156 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003157
solenberg76377c52017-02-21 00:54:31 -08003158 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3159 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3160 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3161 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3162 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003163 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003164
solenberg76377c52017-02-21 00:54:31 -08003165 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3166 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3167 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3168 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3169 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003170 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003171
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003172 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003173 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3174 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003175 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003176 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003177 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003178 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003179 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3180 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3181 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3182 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3183 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003184 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003185 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3186 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3187 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003188 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003189}
3190
wu@webrtc.orgde305012013-10-31 15:40:38 +00003191// This test verifies DSCP settings are properly applied on voice media channel.
3192TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003193 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003194 cricket::FakeNetworkInterface network_interface;
3195 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003196 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003197
solenberg059fb442016-10-26 05:12:24 -07003198 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3199 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3200
solenbergbc37fc82016-04-04 09:54:44 -07003201 channel.reset(
3202 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003203 channel->SetInterface(&network_interface);
3204 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3205 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3206
3207 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003208 channel.reset(
3209 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003210 channel->SetInterface(&network_interface);
3211 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3212
3213 // Verify that setting the option to false resets the
3214 // DiffServCodePoint.
3215 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003216 channel.reset(
3217 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003218 channel->SetInterface(&network_interface);
3219 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3220 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3221
3222 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003223}
3224
solenberg1ac56142015-10-13 03:58:19 -07003225TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003226 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003227 cricket::WebRtcVoiceMediaChannel* media_channel =
3228 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003229 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg8189b022016-06-14 12:13:00 -07003230 EXPECT_TRUE(AddRecvStream(kSsrc1));
solenberg1ac56142015-10-13 03:58:19 -07003231 int channel_id = voe_.GetLastChannel();
3232 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
3233 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
solenberg8189b022016-06-14 12:13:00 -07003234 EXPECT_TRUE(AddRecvStream(kSsrc2));
solenberg1ac56142015-10-13 03:58:19 -07003235 int channel_id2 = voe_.GetLastChannel();
3236 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003237}
3238
solenberg1ac56142015-10-13 03:58:19 -07003239TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003240 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003241 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003242 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3243 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3244 EXPECT_TRUE(channel_->AddSendStream(
3245 cricket::StreamParams::CreateLegacy(kSsrc1)));
3246 int channel_id = voe_.GetLastChannel();
3247 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
3248 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
3249 EXPECT_TRUE(channel_->AddSendStream(
3250 cricket::StreamParams::CreateLegacy(kSsrc2)));
3251 int channel_id2 = voe_.GetLastChannel();
3252 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003253}
3254
solenberg4bac9c52015-10-09 02:32:53 -07003255TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003256 EXPECT_TRUE(SetupChannel());
solenberg4bac9c52015-10-09 02:32:53 -07003257 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003258 cricket::StreamParams stream;
3259 stream.ssrcs.push_back(kSsrc2);
3260 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg217fb662016-06-17 08:30:54 -07003261 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
solenberg4bac9c52015-10-09 02:32:53 -07003262 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
solenberg217fb662016-06-17 08:30:54 -07003263 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
solenberg1ac56142015-10-13 03:58:19 -07003264}
3265
3266TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003267 EXPECT_TRUE(SetupChannel());
solenberg1ac56142015-10-13 03:58:19 -07003268 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
3269 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg217fb662016-06-17 08:30:54 -07003270 EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
solenberg1ac56142015-10-13 03:58:19 -07003271 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
solenberg217fb662016-06-17 08:30:54 -07003272 EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
3273 EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
3274 EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003275}
3276
pbos8fc7fa72015-07-15 08:02:58 -07003277TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003278 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003279 const std::string kSyncLabel = "AvSyncLabel";
3280
solenbergff976312016-03-30 23:28:51 -07003281 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003282 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3283 sp.sync_label = kSyncLabel;
3284 // Creating two channels to make sure that sync label is set properly for both
3285 // the default voice channel and following ones.
3286 EXPECT_TRUE(channel_->AddRecvStream(sp));
3287 sp.ssrcs[0] += 1;
3288 EXPECT_TRUE(channel_->AddRecvStream(sp));
3289
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003290 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003291 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003292 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003293 << "SyncGroup should be set based on sync_label";
3294 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003295 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003296 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003297}
3298
solenberg3a941542015-11-16 07:34:50 -08003299// TODO(solenberg): Remove, once recv streams are configured through Call.
3300// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003301TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003302 // Test that setting the header extensions results in the expected state
3303 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003304 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003305 ssrcs.push_back(223);
3306 ssrcs.push_back(224);
3307
solenbergff976312016-03-30 23:28:51 -07003308 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003309 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003310 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003311 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003312 cricket::StreamParams::CreateLegacy(ssrc)));
3313 }
3314
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003315 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003316 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003317 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003318 EXPECT_NE(nullptr, s);
3319 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3320 }
3321
3322 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003323 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003324 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003325 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003326 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003327 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003328 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003329 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003330 EXPECT_NE(nullptr, s);
3331 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003332 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3333 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003334 for (const auto& s_ext : s_exts) {
3335 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003336 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003337 }
3338 }
3339 }
3340 }
3341
3342 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003343 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003344 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003345 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003346 EXPECT_NE(nullptr, s);
3347 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3348 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003349}
3350
3351TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3352 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003353 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003354 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003355 static const unsigned char kRtcp[] = {
3356 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3357 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3360 };
jbaucheec21bd2016-03-20 06:15:43 -07003361 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003362
solenbergff976312016-03-30 23:28:51 -07003363 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003364 cricket::WebRtcVoiceMediaChannel* media_channel =
3365 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003366 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003367 EXPECT_TRUE(media_channel->AddRecvStream(
3368 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3369
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003370 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003372 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003373 EXPECT_EQ(0, s->received_packets());
3374 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3375 EXPECT_EQ(1, s->received_packets());
3376 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3377 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003378}
Minyue2013aec2015-05-13 14:14:42 +02003379
solenberg0a617e22015-10-20 15:49:38 -07003380// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003381// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003382TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003383 EXPECT_TRUE(SetupSendStream());
solenberg7602aab2016-11-14 11:30:07 -08003384 EXPECT_TRUE(AddRecvStream(kSsrc2));
3385 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3386 EXPECT_TRUE(channel_->AddSendStream(
3387 cricket::StreamParams::CreateLegacy(kSsrc3)));
3388 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
3389 EXPECT_TRUE(AddRecvStream(kSsrc4));
3390 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc4).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003391}
3392
solenberg7602aab2016-11-14 11:30:07 -08003393TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3394 EXPECT_TRUE(SetupRecvStream());
3395 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3396 EXPECT_TRUE(channel_->AddSendStream(
3397 cricket::StreamParams::CreateLegacy(kSsrc2)));
3398 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3399 EXPECT_TRUE(AddRecvStream(kSsrc3));
3400 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
3401 EXPECT_TRUE(channel_->AddSendStream(
3402 cricket::StreamParams::CreateLegacy(kSsrc4)));
3403 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc1).rtp.local_ssrc);
3404 EXPECT_EQ(kSsrc2, GetRecvStreamConfig(kSsrc3).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003405}
stefan658910c2015-09-03 05:48:32 -07003406
deadbeef884f5852016-01-15 09:20:04 -08003407TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003408 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003409 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3410 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003411
3412 // Setting the sink before a recv stream exists should do nothing.
3413 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
solenberg8189b022016-06-14 12:13:00 -07003414 EXPECT_TRUE(AddRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003415 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3416
3417 // Now try actually setting the sink.
3418 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3419 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3420
3421 // Now try resetting it.
3422 channel_->SetRawAudioSink(kSsrc1, nullptr);
3423 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3424}
3425
3426TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003427 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003428 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3429 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003430
3431 // Should be able to set a default sink even when no stream exists.
3432 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3433
3434 // Create default channel and ensure it's assigned the default sink.
3435 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3436 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3437
3438 // Try resetting the default sink.
3439 channel_->SetRawAudioSink(0, nullptr);
3440 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3441
3442 // Try setting the default sink while the default stream exists.
3443 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3444 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3445
3446 // If we remove and add a default stream, it should get the same sink.
3447 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3448 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3449 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3450}
3451
skvlad7a43d252016-03-22 15:32:27 -07003452// Test that, just like the video channel, the voice channel communicates the
3453// network state to the call.
3454TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003455 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003456
3457 EXPECT_EQ(webrtc::kNetworkUp,
3458 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3459 EXPECT_EQ(webrtc::kNetworkUp,
3460 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3461
3462 channel_->OnReadyToSend(false);
3463 EXPECT_EQ(webrtc::kNetworkDown,
3464 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3465 EXPECT_EQ(webrtc::kNetworkUp,
3466 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3467
3468 channel_->OnReadyToSend(true);
3469 EXPECT_EQ(webrtc::kNetworkUp,
3470 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3471 EXPECT_EQ(webrtc::kNetworkUp,
3472 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3473}
3474
aleloi18e0b672016-10-04 02:45:47 -07003475// Test that playout is still started after changing parameters
3476TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3477 SetupRecvStream();
3478 channel_->SetPlayout(true);
3479 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3480
3481 // Changing RTP header extensions will recreate the AudioReceiveStream.
3482 cricket::AudioRecvParameters parameters;
3483 parameters.extensions.push_back(
3484 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3485 channel_->SetRecvParameters(parameters);
3486
3487 EXPECT_TRUE(GetRecvStream(kSsrc1).started());
3488}
3489
stefan658910c2015-09-03 05:48:32 -07003490// Tests that the library initializes and shuts down properly.
3491TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003492 // If the VoiceEngine wants to gather available codecs early, that's fine but
3493 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003494 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003495 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003496 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003497 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003498 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003499 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3500 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003501 EXPECT_TRUE(channel != nullptr);
3502 delete channel;
solenbergff976312016-03-30 23:28:51 -07003503}
stefan658910c2015-09-03 05:48:32 -07003504
solenbergff976312016-03-30 23:28:51 -07003505// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003506TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3507 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3508 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3509 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
solenbergff976312016-03-30 23:28:51 -07003510 {
ossuc54071d2016-08-17 02:45:41 -07003511 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003512 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003513 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003514 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003515 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003516 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3517 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3518 EXPECT_TRUE(channel != nullptr);
3519 delete channel;
3520 }
stefan658910c2015-09-03 05:48:32 -07003521}
3522
3523// Tests that the library is configured with the codecs we want.
3524TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003525 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3526 // module.
3527
stefan658910c2015-09-03 05:48:32 -07003528 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003529#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003530 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003531 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003532#endif
3533#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003534 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003535 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003536#endif
3537#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003538 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003539 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003540#endif
3541#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003542 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003543 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003544 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003545 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003546 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003547#endif
solenberg26c8c912015-11-27 04:00:25 -08003548 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003549 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003550 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003551 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003552 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003553 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003554 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3555 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3556 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3557 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3558 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3559 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003560 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003561 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003562 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003563 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003564 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003565 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003566 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003567 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003568 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003569 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003570 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003571 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003572 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003573 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003574 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003575 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003576 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003577 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003578 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003579 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003580 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003581 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003582 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003583
stefan658910c2015-09-03 05:48:32 -07003584 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003585 // TODO(ossu): Why are the payload types of codecs with non-static payload
3586 // type assignments checked here? It shouldn't really matter.
3587 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003588 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003589 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3590 if (codec.name == "CN" && codec.clockrate == 16000) {
3591 EXPECT_EQ(105, codec.id);
3592 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3593 EXPECT_EQ(106, codec.id);
3594 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3595 EXPECT_EQ(103, codec.id);
3596 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3597 EXPECT_EQ(104, codec.id);
3598 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3599 EXPECT_EQ(9, codec.id);
3600 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3601 EXPECT_EQ(126, codec.id);
3602 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3603 // Remove these checks once both send and receive side assigns payload types
3604 // dynamically.
3605 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3606 EXPECT_EQ(113, codec.id);
3607 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3608 EXPECT_EQ(112, codec.id);
3609 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3610 EXPECT_EQ(110, codec.id);
3611 } else if (codec.name == "opus") {
3612 EXPECT_EQ(111, codec.id);
3613 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3614 EXPECT_EQ("10", codec.params.find("minptime")->second);
3615 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3616 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003617 }
3618 }
stefan658910c2015-09-03 05:48:32 -07003619}
3620
3621// Tests that VoE supports at least 32 channels
3622TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003623 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003624 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003625 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003626 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003627 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003628
3629 cricket::VoiceMediaChannel* channels[32];
3630 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003631 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003632 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3633 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003634 if (!channel)
3635 break;
stefan658910c2015-09-03 05:48:32 -07003636 channels[num_channels++] = channel;
3637 }
3638
tfarina5237aaf2015-11-10 23:44:30 -08003639 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003640 EXPECT_EQ(expected, num_channels);
3641
3642 while (num_channels > 0) {
3643 delete channels[--num_channels];
3644 }
stefan658910c2015-09-03 05:48:32 -07003645}
3646
3647// Test that we set our preferred codecs properly.
3648TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003649 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3650 // - Check that our builtin codecs are usable by Channel.
3651 // - The codecs provided by the engine is usable by Channel.
3652 // It does not check that the codecs in the RecvParameters are actually
3653 // what we sent in - though it's probably reasonable to expect so, if
3654 // SetRecvParameters returns true.
3655 // I think it will become clear once audio decoder injection is completed.
3656 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003657 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003658 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003659 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003660 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003661 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3662 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003663 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003664 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003665 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003666}
ossu9def8002017-02-09 05:14:32 -08003667
3668TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3669 std::vector<webrtc::AudioCodecSpec> specs;
3670 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3671 spec1.allow_comfort_noise = false;
3672 spec1.supports_network_adaption = true;
3673 specs.push_back(spec1);
3674 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3675 spec2.allow_comfort_noise = false;
3676 specs.push_back(spec2);
3677 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3678 {{"param1", "value1b"},
3679 {"param2", "value2"}}}));
3680 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3681 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3682
3683 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3684 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3685 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3686 .WillOnce(Return(specs));
3687
3688 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3689 auto codecs = engine.recv_codecs();
3690 EXPECT_EQ(11, codecs.size());
3691
3692 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3693 // check the actual values safely, to provide better test results.
3694 auto get_codec =
3695 [&codecs](size_t index) -> const cricket::AudioCodec& {
3696 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3697 if (codecs.size() > index)
3698 return codecs[index];
3699 return missing_codec;
3700 };
3701
3702 // Ensure the general codecs are generated first and in order.
3703 for (size_t i = 0; i != specs.size(); ++i) {
3704 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3705 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3706 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3707 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3708 }
3709
3710 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003711 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003712 auto find_codec =
3713 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3714 for (size_t i = 0; i != codecs.size(); ++i) {
3715 const cricket::AudioCodec& codec = codecs[i];
3716 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3717 codec.clockrate == format.clockrate_hz &&
3718 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003719 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003720 }
3721 }
3722 return -1;
3723 };
3724
3725 // Ensure all supplementary codecs are generated last. Their internal ordering
3726 // is not important.
3727 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3728 const int num_specs = static_cast<int>(specs.size());
3729 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3730 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3731 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3732 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3733 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3734 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3735 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3736}