blob: e72a9a0152b29e81296838a58bb053f8b8895f28 [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
solenberg2100c0b2017-03-01 11:29:29 -080051const uint32_t kSsrc0 = 0;
52const uint32_t kSsrc1 = 1;
53const uint32_t kSsrcX = 0x99;
54const uint32_t kSsrcY = 0x17;
55const uint32_t kSsrcZ = 0x42;
56const uint32_t kSsrcW = 0x02;
57const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000058
solenberg971cab02016-06-14 10:02:41 -070059constexpr int kRtpHistoryMs = 5000;
60
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061class FakeVoEWrapper : public cricket::VoEWrapper {
62 public:
63 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg76377c52017-02-21 00:54:31 -080064 : cricket::VoEWrapper(engine, // base
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 engine, // codec
solenberg796b8f92017-03-01 17:02:23 -080066 engine) { // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067 }
68};
skvlad11a9cbf2016-10-07 11:53:05 -070069
solenberg76377c52017-02-21 00:54:31 -080070class MockTransmitMixer : public webrtc::voe::TransmitMixer {
71 public:
72 MockTransmitMixer() = default;
73 virtual ~MockTransmitMixer() = default;
74
75 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
76};
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020077} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
solenbergff976312016-03-30 23:28:51 -070079// Tests that our stub library "works".
80TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070081 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
82 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
83 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070084 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
85 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
86 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -080087 EXPECT_CALL(adm, SetAGC(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -070088 StrictMock<webrtc::test::MockAudioProcessing> apm;
89 EXPECT_CALL(apm, ApplyConfig(testing::_));
90 EXPECT_CALL(apm, SetExtraOptions(testing::_));
91 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -080092 StrictMock<MockTransmitMixer> transmit_mixer;
93 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
94 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -070095 EXPECT_FALSE(voe.IsInited());
96 {
ossuc54071d2016-08-17 02:45:41 -070097 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -080098 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -070099 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700100 EXPECT_TRUE(voe.IsInited());
101 }
102 EXPECT_FALSE(voe.IsInited());
103}
104
deadbeef884f5852016-01-15 09:20:04 -0800105class FakeAudioSink : public webrtc::AudioSinkInterface {
106 public:
107 void OnData(const Data& audio) override {}
108};
109
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800110class FakeAudioSource : public cricket::AudioSource {
111 void SetSink(Sink* sink) override {}
112};
113
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114class WebRtcVoiceEngineTestFake : public testing::Test {
115 public:
stefanba4c0e42016-02-04 04:12:24 -0800116 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
117
118 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800119 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
120 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
121 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700122 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800123 // AudioDeviceModule.
solenbergbc37fc82016-04-04 09:54:44 -0700124 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
125 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700126 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
127 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
128 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -0800129 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
130 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700131 EXPECT_CALL(apm_, ApplyConfig(testing::_));
132 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
133 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800134 // Default Options.
135 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
136 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
137 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
138 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
139 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
140 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
141 // Init does not overwrite default AGC config.
142 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
143 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
144 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
145 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
146 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
147 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800148 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
149 // the tests here probe the specific set of codecs provided by the builtin
150 // factory. Those tests should probably be moved elsewhere.
151 engine_.reset(new cricket::WebRtcVoiceEngine(
152 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
153 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200154 send_parameters_.codecs.push_back(kPcmuCodec);
155 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800156 // Default Options.
157 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 }
solenberg8189b022016-06-14 12:13:00 -0700159
solenbergff976312016-03-30 23:28:51 -0700160 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700161 EXPECT_CALL(apm_, ApplyConfig(testing::_));
162 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700163 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
164 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200165 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000166 }
solenberg8189b022016-06-14 12:13:00 -0700167
solenbergff976312016-03-30 23:28:51 -0700168 bool SetupRecvStream() {
169 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700170 return false;
171 }
solenberg2100c0b2017-03-01 11:29:29 -0800172 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700173 }
solenberg8189b022016-06-14 12:13:00 -0700174
solenbergff976312016-03-30 23:28:51 -0700175 bool SetupSendStream() {
176 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000177 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000178 }
solenberg2100c0b2017-03-01 11:29:29 -0800179 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800180 return false;
181 }
solenberg059fb442016-10-26 05:12:24 -0700182 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800183 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000184 }
solenberg8189b022016-06-14 12:13:00 -0700185
186 bool AddRecvStream(uint32_t ssrc) {
187 EXPECT_TRUE(channel_);
188 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
189 }
190
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000191 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700192 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700193 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800194 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
195 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700196 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800197 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000198 }
solenberg8189b022016-06-14 12:13:00 -0700199
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700201 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000202 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 }
solenberg8189b022016-06-14 12:13:00 -0700204
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200205 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 }
208
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100209 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
210 const auto* send_stream = call_.GetAudioSendStream(ssrc);
211 EXPECT_TRUE(send_stream);
212 return *send_stream;
213 }
214
deadbeef884f5852016-01-15 09:20:04 -0800215 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
216 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
217 EXPECT_TRUE(recv_stream);
218 return *recv_stream;
219 }
220
solenberg3a941542015-11-16 07:34:50 -0800221 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800222 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800223 }
224
solenberg7add0582015-11-20 09:59:34 -0800225 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800226 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800227 }
228
solenberg059fb442016-10-26 05:12:24 -0700229 void SetSend(bool enable) {
230 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700231 if (enable) {
232 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
233 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
234 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700235 EXPECT_CALL(apm_, ApplyConfig(testing::_));
236 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700237 }
solenberg059fb442016-10-26 05:12:24 -0700238 channel_->SetSend(enable);
239 }
240
241 void SetSendParameters(const cricket::AudioSendParameters& params) {
242 EXPECT_CALL(apm_, ApplyConfig(testing::_));
243 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
244 ASSERT_TRUE(channel_);
245 EXPECT_TRUE(channel_->SetSendParameters(params));
246 }
247
minyue6b825df2016-10-31 04:08:32 -0700248 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
249 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700250 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
251 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700252 if (enable && options) {
253 EXPECT_CALL(apm_, ApplyConfig(testing::_));
254 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
255 }
256 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700257 }
258
solenbergffbbcac2016-11-17 05:25:37 -0800259 void TestInsertDtmf(uint32_t ssrc, bool caller,
260 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700261 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000262 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700263 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000264 // send stream.
265 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800266 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000267 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000268
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700270 SetSendParameters(send_parameters_);
271 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800273 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800274 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700275 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000277
278 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700279 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800280 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000281 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800282 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000283 }
284
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800286 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100288 // Test send.
289 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800290 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100291 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800292 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800293 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800294 EXPECT_EQ(codec.id, telephone_event.payload_type);
295 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100296 EXPECT_EQ(2, telephone_event.event_code);
297 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 }
299
300 // Test that send bandwidth is set correctly.
301 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000302 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
303 // |expected_result| is the expected result from SetMaxSendBandwidth().
304 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700305 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
306 int max_bitrate,
307 bool expected_result,
308 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200309 cricket::AudioSendParameters parameters;
310 parameters.codecs.push_back(codec);
311 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700312 if (expected_result) {
313 SetSendParameters(parameters);
314 } else {
315 EXPECT_FALSE(channel_->SetSendParameters(parameters));
316 }
solenberg2100c0b2017-03-01 11:29:29 -0800317 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 }
319
skvlade0d46372016-04-07 22:59:22 -0700320 // Sets the per-stream maximum bitrate limit for the specified SSRC.
321 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700322 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700323 EXPECT_EQ(1UL, parameters.encodings.size());
324
deadbeefe702b302017-02-04 12:09:01 -0800325 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700326 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700327 }
328
solenberg059fb442016-10-26 05:12:24 -0700329 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700330 cricket::AudioSendParameters send_parameters;
331 send_parameters.codecs.push_back(codec);
332 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700333 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700334 }
335
minyue7a973442016-10-20 03:27:12 -0700336 void CheckSendCodec(int32_t ssrc,
337 const char expected_name[],
338 int expected_channels,
339 int expected_bitrate) {
340 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
341 EXPECT_STREQ(expected_name, codec.plname);
342 EXPECT_EQ(expected_channels, codec.channels);
343 EXPECT_EQ(expected_bitrate, codec.rate);
344 }
345
346 int GetOpusMaxPlaybackRate(int32_t ssrc) {
347 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
348 }
349
350 bool GetOpusDtx(int32_t ssrc) {
351 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
352 }
353
354 bool GetCodecFec(int32_t ssrc) {
355 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
356 }
357
skvlade0d46372016-04-07 22:59:22 -0700358 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700359 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
360 }
361
362 int GetCodecPacSize(int32_t ssrc) {
363 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700364 }
365
minyue6b825df2016-10-31 04:08:32 -0700366 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
367 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
368 }
369
skvlade0d46372016-04-07 22:59:22 -0700370 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
371 int global_max,
372 int stream_max,
373 bool expected_result,
374 int expected_codec_bitrate) {
375 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800376 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700377
378 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700379 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800380 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700381
382 // Verify that reading back the parameters gives results
383 // consistent with the Set() result.
384 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800385 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700386 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
387 EXPECT_EQ(expected_result ? stream_max : -1,
388 resulting_parameters.encodings[0].max_bitrate_bps);
389
390 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800391 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700392 }
393
stefan13f1a0a2016-11-30 07:22:58 -0800394 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
395 int expected_min_bitrate_bps,
396 const char* start_bitrate_kbps,
397 int expected_start_bitrate_bps,
398 const char* max_bitrate_kbps,
399 int expected_max_bitrate_bps) {
400 EXPECT_TRUE(SetupSendStream());
401 auto& codecs = send_parameters_.codecs;
402 codecs.clear();
403 codecs.push_back(kOpusCodec);
404 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
405 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
406 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
407 SetSendParameters(send_parameters_);
408
409 EXPECT_EQ(expected_min_bitrate_bps,
410 call_.GetConfig().bitrate_config.min_bitrate_bps);
411 EXPECT_EQ(expected_start_bitrate_bps,
412 call_.GetConfig().bitrate_config.start_bitrate_bps);
413 EXPECT_EQ(expected_max_bitrate_bps,
414 call_.GetConfig().bitrate_config.max_bitrate_bps);
415 }
416
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000417 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700418 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000419
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000420 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800421 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000422
423 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700424 send_parameters_.extensions.push_back(
425 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700426 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800427 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000428
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000429 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200430 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700431 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800432 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000433
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000434 // Ensure extension is set properly.
435 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700436 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700437 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800438 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
439 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
440 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000441
solenberg7add0582015-11-20 09:59:34 -0800442 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000443 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800444 cricket::StreamParams::CreateLegacy(kSsrcY)));
445 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
446 call_.GetAudioSendStream(kSsrcY));
447 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
448 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
449 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450
451 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200452 send_parameters_.codecs.push_back(kPcmuCodec);
453 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700454 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800455 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000457 }
458
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000459 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700460 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000461
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000462 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800463 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000464
465 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700466 recv_parameters_.extensions.push_back(
467 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800468 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800469 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000470
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000471 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800472 recv_parameters_.extensions.clear();
473 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800474 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000475
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000476 // Ensure extension is set properly.
477 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700478 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800479 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800480 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
481 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
482 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000483
solenberg7add0582015-11-20 09:59:34 -0800484 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_TRUE(AddRecvStream(kSsrcY));
486 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
487 call_.GetAudioReceiveStream(kSsrcY));
488 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
489 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
490 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000491
492 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800493 recv_parameters_.extensions.clear();
494 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
496 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000497 }
498
solenberg85a04962015-10-27 03:35:21 -0700499 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
500 webrtc::AudioSendStream::Stats stats;
501 stats.local_ssrc = 12;
502 stats.bytes_sent = 345;
503 stats.packets_sent = 678;
504 stats.packets_lost = 9012;
505 stats.fraction_lost = 34.56f;
506 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800507 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700508 stats.ext_seqnum = 789;
509 stats.jitter_ms = 12;
510 stats.rtt_ms = 345;
511 stats.audio_level = 678;
512 stats.aec_quality_min = 9.01f;
513 stats.echo_delay_median_ms = 234;
514 stats.echo_delay_std_ms = 567;
515 stats.echo_return_loss = 890;
516 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700517 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800518 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700519 stats.typing_noise_detected = true;
520 return stats;
521 }
522 void SetAudioSendStreamStats() {
523 for (auto* s : call_.GetAudioSendStreams()) {
524 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200525 }
solenberg85a04962015-10-27 03:35:21 -0700526 }
solenberg566ef242015-11-06 15:34:49 -0800527 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
528 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700529 const auto stats = GetAudioSendStreamStats();
530 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
531 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
532 EXPECT_EQ(info.packets_sent, stats.packets_sent);
533 EXPECT_EQ(info.packets_lost, stats.packets_lost);
534 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
535 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800536 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700537 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
538 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
539 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
540 EXPECT_EQ(info.audio_level, stats.audio_level);
541 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
542 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
543 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
544 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
545 EXPECT_EQ(info.echo_return_loss_enhancement,
546 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700547 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800548 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
549 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800550 EXPECT_EQ(info.typing_noise_detected,
551 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700552 }
553
554 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
555 webrtc::AudioReceiveStream::Stats stats;
556 stats.remote_ssrc = 123;
557 stats.bytes_rcvd = 456;
558 stats.packets_rcvd = 768;
559 stats.packets_lost = 101;
560 stats.fraction_lost = 23.45f;
561 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800562 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700563 stats.ext_seqnum = 678;
564 stats.jitter_ms = 901;
565 stats.jitter_buffer_ms = 234;
566 stats.jitter_buffer_preferred_ms = 567;
567 stats.delay_estimate_ms = 890;
568 stats.audio_level = 1234;
569 stats.expand_rate = 5.67f;
570 stats.speech_expand_rate = 8.90f;
571 stats.secondary_decoded_rate = 1.23f;
572 stats.accelerate_rate = 4.56f;
573 stats.preemptive_expand_rate = 7.89f;
574 stats.decoding_calls_to_silence_generator = 12;
575 stats.decoding_calls_to_neteq = 345;
576 stats.decoding_normal = 67890;
577 stats.decoding_plc = 1234;
578 stats.decoding_cng = 5678;
579 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700580 stats.decoding_muted_output = 3456;
581 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200582 return stats;
583 }
584 void SetAudioReceiveStreamStats() {
585 for (auto* s : call_.GetAudioReceiveStreams()) {
586 s->SetStats(GetAudioReceiveStreamStats());
587 }
588 }
589 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700590 const auto stats = GetAudioReceiveStreamStats();
591 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
592 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
593 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
594 EXPECT_EQ(info.packets_lost, stats.packets_lost);
595 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
596 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800597 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700598 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
599 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
600 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200601 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700602 stats.jitter_buffer_preferred_ms);
603 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
604 EXPECT_EQ(info.audio_level, stats.audio_level);
605 EXPECT_EQ(info.expand_rate, stats.expand_rate);
606 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
607 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
608 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
609 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200610 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700611 stats.decoding_calls_to_silence_generator);
612 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
613 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
614 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
615 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
616 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700617 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700618 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200619 }
hbos1acfbd22016-11-17 23:43:29 -0800620 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
621 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
622 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
623 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
624 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
625 codec.ToCodecParameters());
626 }
627 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
628 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
629 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
630 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
631 codec.ToCodecParameters());
632 }
633 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200634
peah8271d042016-11-22 07:24:52 -0800635 bool IsHighPassFilterEnabled() {
636 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
637 }
638
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700640 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700641 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800642 webrtc::test::MockGainControl& apm_gc_;
643 webrtc::test::MockEchoCancellation& apm_ec_;
644 webrtc::test::MockNoiseSuppression& apm_ns_;
645 webrtc::test::MockVoiceDetection& apm_vd_;
646 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700647 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200648 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700650 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700651 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200652 cricket::AudioSendParameters send_parameters_;
653 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800654 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800655 private:
656 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657};
658
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000659// Tests that we can create and destroy a channel.
660TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700661 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662}
663
solenberg31fec402016-05-06 02:13:12 -0700664// Test that we can add a send stream and that it has the correct defaults.
665TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
666 EXPECT_TRUE(SetupChannel());
667 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800668 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
669 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
670 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700671 EXPECT_EQ("", config.rtp.c_name);
672 EXPECT_EQ(0u, config.rtp.extensions.size());
673 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
674 config.send_transport);
675}
676
677// Test that we can add a receive stream and that it has the correct defaults.
678TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
679 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800680 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700681 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800682 GetRecvStreamConfig(kSsrcX);
683 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700684 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
685 EXPECT_FALSE(config.rtp.transport_cc);
686 EXPECT_EQ(0u, config.rtp.extensions.size());
687 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
688 config.rtcp_send_transport);
689 EXPECT_EQ("", config.sync_group);
690}
691
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700693// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700694// TODO(ossu): This test should move into a separate builtin audio codecs
695// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700696TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700697 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 ASSERT_FALSE(codecs.empty());
699 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
700 EXPECT_EQ(48000, codecs[0].clockrate);
701 EXPECT_EQ(2, codecs[0].channels);
702 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703}
704
stefanba4c0e42016-02-04 04:12:24 -0800705TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700706 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800707 bool opus_found = false;
708 for (cricket::AudioCodec codec : codecs) {
709 if (codec.name == "opus") {
710 EXPECT_TRUE(HasTransportCc(codec));
711 opus_found = true;
712 }
713 }
714 EXPECT_TRUE(opus_found);
715}
716
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717// Tests that we can find codecs by name or id, and that we interpret the
718// clockrate and bitrate fields properly.
719TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
720 cricket::AudioCodec codec;
721 webrtc::CodecInst codec_inst;
722 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800723 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800725 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800727 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
728 &codec_inst));
729 // Find telephone-event with explicit clockrate and 0 bitrate.
730 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800731 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732 // Find ISAC with a different payload id.
733 codec = kIsacCodec;
734 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800735 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736 EXPECT_EQ(codec.id, codec_inst.pltype);
737 // Find PCMU with a 0 clockrate.
738 codec = kPcmuCodec;
739 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800740 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 EXPECT_EQ(codec.id, codec_inst.pltype);
742 EXPECT_EQ(8000, codec_inst.plfreq);
743 // Find PCMU with a 0 bitrate.
744 codec = kPcmuCodec;
745 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800746 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747 EXPECT_EQ(codec.id, codec_inst.pltype);
748 EXPECT_EQ(64000, codec_inst.rate);
749 // Find ISAC with an explicit bitrate.
750 codec = kIsacCodec;
751 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800752 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000753 EXPECT_EQ(codec.id, codec_inst.pltype);
754 EXPECT_EQ(32000, codec_inst.rate);
755}
756
757// Test that we set our inbound codecs properly, including changing PT.
758TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700759 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200760 cricket::AudioRecvParameters parameters;
761 parameters.codecs.push_back(kIsacCodec);
762 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800763 parameters.codecs.push_back(kTelephoneEventCodec1);
764 parameters.codecs.push_back(kTelephoneEventCodec2);
765 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200766 parameters.codecs[2].id = 126;
767 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800768 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700769 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800770
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800772 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 gcodec.plfreq = 16000;
774 gcodec.channels = 1;
775 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
776 EXPECT_EQ(106, gcodec.pltype);
777 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800778
tfarina5237aaf2015-11-10 23:44:30 -0800779 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 gcodec.plfreq = 8000;
781 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
782 EXPECT_EQ(126, gcodec.pltype);
783 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800784
785 gcodec.plfreq = 32000;
786 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
787 EXPECT_EQ(107, gcodec.pltype);
788 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail to set an unknown inbound codec.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700796 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798}
799
800// Test that we fail if we have duplicate types in the inbound list.
801TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700802 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200803 cricket::AudioRecvParameters parameters;
804 parameters.codecs.push_back(kIsacCodec);
805 parameters.codecs.push_back(kCn16000Codec);
806 parameters.codecs[1].id = kIsacCodec.id;
807 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that we can decode OPUS without stereo parameters.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
816 parameters.codecs.push_back(kOpusCodec);
817 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800818 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700819 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800821 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 // Even without stereo parameters, recv codecs still specify channels = 2.
823 EXPECT_EQ(2, opus.channels);
824 EXPECT_EQ(111, opus.pltype);
825 EXPECT_STREQ("opus", opus.plname);
826 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700827 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 EXPECT_EQ(111, opus.pltype);
829}
830
831// Test that we can decode OPUS with stereo = 0.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
837 parameters.codecs.push_back(kOpusCodec);
838 parameters.codecs[2].params["stereo"] = "0";
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841 int channel_num2 = voe_.GetLastChannel();
842 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800843 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844 // Even when stereo is off, recv codecs still specify channels = 2.
845 EXPECT_EQ(2, opus.channels);
846 EXPECT_EQ(111, opus.pltype);
847 EXPECT_STREQ("opus", opus.plname);
848 opus.pltype = 0;
849 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
850 EXPECT_EQ(111, opus.pltype);
851}
852
853// Test that we can decode OPUS with stereo = 1.
854TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700855 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 cricket::AudioRecvParameters parameters;
857 parameters.codecs.push_back(kIsacCodec);
858 parameters.codecs.push_back(kPcmuCodec);
859 parameters.codecs.push_back(kOpusCodec);
860 parameters.codecs[2].params["stereo"] = "1";
861 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800862 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863 int channel_num2 = voe_.GetLastChannel();
864 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800865 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866 EXPECT_EQ(2, opus.channels);
867 EXPECT_EQ(111, opus.pltype);
868 EXPECT_STREQ("opus", opus.plname);
869 opus.pltype = 0;
870 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
871 EXPECT_EQ(111, opus.pltype);
872}
873
874// Test that changes to recv codecs are applied to all streams.
875TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700876 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200877 cricket::AudioRecvParameters parameters;
878 parameters.codecs.push_back(kIsacCodec);
879 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800880 parameters.codecs.push_back(kTelephoneEventCodec1);
881 parameters.codecs.push_back(kTelephoneEventCodec2);
882 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200883 parameters.codecs[2].id = 126;
884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800885 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000886 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800887
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800889 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 gcodec.plfreq = 16000;
891 gcodec.channels = 1;
892 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
893 EXPECT_EQ(106, gcodec.pltype);
894 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800895
tfarina5237aaf2015-11-10 23:44:30 -0800896 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897 gcodec.plfreq = 8000;
898 gcodec.channels = 1;
899 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
900 EXPECT_EQ(126, gcodec.pltype);
901 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800902
903 gcodec.plfreq = 32000;
904 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
905 EXPECT_EQ(107, gcodec.pltype);
906 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907}
908
909TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700910 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 cricket::AudioRecvParameters parameters;
912 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800913 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
solenberg2100c0b2017-03-01 11:29:29 -0800916 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800917 ASSERT_EQ(1, dm.count(106));
918 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919}
920
921// Test that we can apply the same set of codecs again while playing.
922TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700923 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 cricket::AudioRecvParameters parameters;
925 parameters.codecs.push_back(kIsacCodec);
926 parameters.codecs.push_back(kCn16000Codec);
927 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700928 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
931 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200932 parameters.codecs[0].id = 127;
933 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800934 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935}
936
937// Test that we can add a codec while playing.
938TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200940 cricket::AudioRecvParameters parameters;
941 parameters.codecs.push_back(kIsacCodec);
942 parameters.codecs.push_back(kCn16000Codec);
943 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700944 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200946 parameters.codecs.push_back(kOpusCodec);
947 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800948 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800950 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
952}
953
954TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000957 // Test that when autobw is enabled, bitrate is kept as the default
958 // value. autobw is enabled for the following tests because the target
959 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960
961 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700962 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
964 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700965 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700968 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700972 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000974 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975
976 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700977 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
978 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
979 // Rates above the max (56000) should be capped.
980 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700983 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
984 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
985 // Rates above the max (510000) should be capped.
986 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987}
988
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000989TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700990 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000991
992 // Test that we can only set a maximum bitrate for a fixed-rate codec
993 // if it's bigger than the fixed rate.
994
995 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700996 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1000 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1001 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1002 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001003}
1004
1005TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001006 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001007 const int kDesiredBitrate = 128000;
1008 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001009 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001010 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001011 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001012
1013 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001014 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001015
solenberg2100c0b2017-03-01 11:29:29 -08001016 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001017}
1018
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019// Test that bitrate cannot be set for CBR codecs.
1020// Bitrate is ignored if it is higher than the fixed bitrate.
1021// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001022TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001023 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024
1025 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001026 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001027 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001028
1029 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001030 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001031 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001032
1033 send_parameters_.max_bandwidth_bps = 128;
1034 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001035 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001036}
1037
skvlade0d46372016-04-07 22:59:22 -07001038// Test that the per-stream bitrate limit and the global
1039// bitrate limit both apply.
1040TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1041 EXPECT_TRUE(SetupSendStream());
1042
1043 // opus, default bitrate == 64000.
1044 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1045 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1046 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1047 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1048
1049 // CBR codecs allow both maximums to exceed the bitrate.
1050 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1051 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1053 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1054
1055 // CBR codecs don't allow per stream maximums to be too low.
1056 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1057 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1058}
1059
1060// Test that an attempt to set RtpParameters for a stream that does not exist
1061// fails.
1062TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1063 EXPECT_TRUE(SetupChannel());
1064 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001065 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001066 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1067
1068 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001070}
1071
1072TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001073 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001074 // This test verifies that setting RtpParameters succeeds only if
1075 // the structure contains exactly one encoding.
1076 // TODO(skvlad): Update this test when we start supporting setting parameters
1077 // for each encoding individually.
1078
1079 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001081 // Two or more encodings should result in failure.
1082 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001084 // Zero encodings should also fail.
1085 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001086 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001087}
1088
1089// Changing the SSRC through RtpParameters is not allowed.
1090TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1091 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001092 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001093 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001094 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001095}
1096
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001097// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001098// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1100 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001101 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001102 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001103 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001104 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105 ASSERT_EQ(1u, parameters.encodings.size());
1106 ASSERT_TRUE(parameters.encodings[0].active);
1107 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1109 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001110
1111 // Now change it back to active and verify we resume sending.
1112 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001113 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1114 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001115}
1116
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001117// Test that SetRtpSendParameters configures the correct encoding channel for
1118// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001119TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1120 SetupForMultiSendStream();
1121 // Create send streams.
1122 for (uint32_t ssrc : kSsrcs4) {
1123 EXPECT_TRUE(
1124 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1125 }
1126 // Configure one stream to be limited by the stream config, another to be
1127 // limited by the global max, and the third one with no per-stream limit
1128 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001129 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001130 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1131 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1132 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1133
1134 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1135 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1136 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1137
1138 // Remove the global cap; the streams should switch to their respective
1139 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001140 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001141 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1142 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1143 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1144}
1145
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001146// Test that GetRtpSendParameters returns the currently configured codecs.
1147TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148 EXPECT_TRUE(SetupSendStream());
1149 cricket::AudioSendParameters parameters;
1150 parameters.codecs.push_back(kIsacCodec);
1151 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001152 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001153
solenberg2100c0b2017-03-01 11:29:29 -08001154 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001156 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1157 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001158}
1159
deadbeefcb443432016-12-12 11:12:36 -08001160// Test that GetRtpSendParameters returns an SSRC.
1161TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1162 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001163 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001164 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001165 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001166}
1167
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001168// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001169TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170 EXPECT_TRUE(SetupSendStream());
1171 cricket::AudioSendParameters parameters;
1172 parameters.codecs.push_back(kIsacCodec);
1173 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001174 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175
solenberg2100c0b2017-03-01 11:29:29 -08001176 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001177
1178 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001179 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001180
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001181 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001182 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1183 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001184}
1185
1186// Test that GetRtpReceiveParameters returns the currently configured codecs.
1187TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1188 EXPECT_TRUE(SetupRecvStream());
1189 cricket::AudioRecvParameters parameters;
1190 parameters.codecs.push_back(kIsacCodec);
1191 parameters.codecs.push_back(kPcmuCodec);
1192 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1193
1194 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001195 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001196 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1197 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1198 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1199}
1200
deadbeefcb443432016-12-12 11:12:36 -08001201// Test that GetRtpReceiveParameters returns an SSRC.
1202TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1203 EXPECT_TRUE(SetupRecvStream());
1204 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001205 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001206 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001207 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001208}
1209
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210// Test that if we set/get parameters multiple times, we get the same results.
1211TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1212 EXPECT_TRUE(SetupRecvStream());
1213 cricket::AudioRecvParameters parameters;
1214 parameters.codecs.push_back(kIsacCodec);
1215 parameters.codecs.push_back(kPcmuCodec);
1216 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1217
1218 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001219 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001220
1221 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001222 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223
1224 // ... And this shouldn't change the params returned by
1225 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001226 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1227 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001228}
1229
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001230// Test that we apply codecs properly.
1231TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001232 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001233 cricket::AudioSendParameters parameters;
1234 parameters.codecs.push_back(kIsacCodec);
1235 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001236 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001237 parameters.codecs[0].id = 96;
1238 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001239 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001240 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001241 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001242 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001243 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1244 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1245 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1246 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1247 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1248 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001249 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001250}
1251
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001252// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1253// to apply.
1254TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001255 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001256 cricket::AudioSendParameters parameters;
1257 parameters.codecs.push_back(kIsacCodec);
1258 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001259 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001260 parameters.codecs[0].id = 96;
1261 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001262 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001263 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001264 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001265 // Calling SetSendCodec again with same codec which is already set.
1266 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001267 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001268 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001269}
1270
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001271// Verify that G722 is set with 16000 samples per second to WebRTC.
1272TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001273 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001274 cricket::AudioSendParameters parameters;
1275 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001276 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001277 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001278 EXPECT_STREQ("G722", gcodec.plname);
1279 EXPECT_EQ(1, gcodec.channels);
1280 EXPECT_EQ(16000, gcodec.plfreq);
1281}
1282
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001283// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001285 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001286 cricket::AudioSendParameters parameters;
1287 parameters.codecs.push_back(kOpusCodec);
1288 parameters.codecs[0].bitrate = 0;
1289 parameters.codecs[0].clockrate = 50000;
1290 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291}
1292
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001293// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001294TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001295 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001296 cricket::AudioSendParameters parameters;
1297 parameters.codecs.push_back(kOpusCodec);
1298 parameters.codecs[0].bitrate = 0;
1299 parameters.codecs[0].channels = 0;
1300 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001303// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001304TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001305 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001306 cricket::AudioSendParameters parameters;
1307 parameters.codecs.push_back(kOpusCodec);
1308 parameters.codecs[0].bitrate = 0;
1309 parameters.codecs[0].channels = 0;
1310 parameters.codecs[0].params["stereo"] = "1";
1311 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312}
1313
1314// Test that if channel is 1 for opus and there's no stereo, we fail.
1315TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001316 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001317 cricket::AudioSendParameters parameters;
1318 parameters.codecs.push_back(kOpusCodec);
1319 parameters.codecs[0].bitrate = 0;
1320 parameters.codecs[0].channels = 1;
1321 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322}
1323
1324// Test that if channel is 1 for opus and stereo=0, we fail.
1325TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001326 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kOpusCodec);
1329 parameters.codecs[0].bitrate = 0;
1330 parameters.codecs[0].channels = 1;
1331 parameters.codecs[0].params["stereo"] = "0";
1332 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
1335// Test that if channel is 1 for opus and stereo=1, we fail.
1336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].channels = 1;
1342 parameters.codecs[0].params["stereo"] = "1";
1343 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
1346// Test that with bitrate=0 and no stereo,
1347// channels and bitrate are 1 and 32000.
1348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001353 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001354 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
1357// Test that with bitrate=0 and stereo=0,
1358// channels and bitrate are 1 and 32000.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001360 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 cricket::AudioSendParameters parameters;
1362 parameters.codecs.push_back(kOpusCodec);
1363 parameters.codecs[0].bitrate = 0;
1364 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001365 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001366 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001367}
1368
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001369// Test that with bitrate=invalid and stereo=0,
1370// channels and bitrate are 1 and 32000.
1371TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001372 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 cricket::AudioSendParameters parameters;
1374 parameters.codecs.push_back(kOpusCodec);
1375 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001376 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001378 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001379 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001380
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001381 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001382 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001383 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001384}
1385
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386// Test that with bitrate=0 and stereo=1,
1387// channels and bitrate are 2 and 64000.
1388TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001389 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 cricket::AudioSendParameters parameters;
1391 parameters.codecs.push_back(kOpusCodec);
1392 parameters.codecs[0].bitrate = 0;
1393 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001394 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001395 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396}
1397
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001398// Test that with bitrate=invalid and stereo=1,
1399// channels and bitrate are 2 and 64000.
1400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001401 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 cricket::AudioSendParameters parameters;
1403 parameters.codecs.push_back(kOpusCodec);
1404 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001405 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001406 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001407 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001408 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001409
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001411 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001412 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001413}
1414
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415// Test that with bitrate=N and stereo unset,
1416// channels and bitrate are 1 and N.
1417TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001418 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 cricket::AudioSendParameters parameters;
1420 parameters.codecs.push_back(kOpusCodec);
1421 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001422 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001423 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424 EXPECT_EQ(111, gcodec.pltype);
1425 EXPECT_EQ(96000, gcodec.rate);
1426 EXPECT_STREQ("opus", gcodec.plname);
1427 EXPECT_EQ(1, gcodec.channels);
1428 EXPECT_EQ(48000, gcodec.plfreq);
1429}
1430
1431// Test that with bitrate=N and stereo=0,
1432// channels and bitrate are 1 and N.
1433TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kOpusCodec);
1437 parameters.codecs[0].bitrate = 30000;
1438 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001440 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441}
1442
1443// Test that with bitrate=N and without any parameters,
1444// channels and bitrate are 1 and N.
1445TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001446 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 cricket::AudioSendParameters parameters;
1448 parameters.codecs.push_back(kOpusCodec);
1449 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001451 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
1454// Test that with bitrate=N and stereo=1,
1455// channels and bitrate are 2 and N.
1456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001457 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 cricket::AudioSendParameters parameters;
1459 parameters.codecs.push_back(kOpusCodec);
1460 parameters.codecs[0].bitrate = 30000;
1461 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001462 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001463 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464}
1465
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001466// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1467// Also test that the "maxaveragebitrate" can't be set to values outside the
1468// range of 6000 and 510000
1469TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001470 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 cricket::AudioSendParameters parameters;
1472 parameters.codecs.push_back(kOpusCodec);
1473 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001474 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001475 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001477 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001478
1479 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001480 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001481 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001482 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001483
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001485 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001486 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001487}
1488
stefan13f1a0a2016-11-30 07:22:58 -08001489TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1490 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1491 200000);
1492}
1493
1494TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1495 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1496}
1497
1498TEST_F(WebRtcVoiceEngineTestFake,
1499 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1500 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1501}
1502
1503TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1504 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1505}
1506
1507TEST_F(WebRtcVoiceEngineTestFake,
1508 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1509 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1510 200000);
1511 send_parameters_.max_bandwidth_bps = 300000;
1512 SetSendParameters(send_parameters_);
1513 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1514 << "Setting max bitrate should keep previous min bitrate.";
1515 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1516 << "Setting max bitrate should not reset start bitrate.";
1517 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1518}
1519
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001520// Test that we can enable NACK with opus as caller.
1521TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001522 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001523 cricket::AudioSendParameters parameters;
1524 parameters.codecs.push_back(kOpusCodec);
1525 parameters.codecs[0].AddFeedbackParam(
1526 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1527 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001528 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001529 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001530 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001531}
1532
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001533// Test that we can enable NACK with opus as callee.
1534TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001535 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001536 cricket::AudioSendParameters parameters;
1537 parameters.codecs.push_back(kOpusCodec);
1538 parameters.codecs[0].AddFeedbackParam(
1539 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1540 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001543 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001544 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001545
1546 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001547 cricket::StreamParams::CreateLegacy(kSsrcX)));
1548 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001549}
1550
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551// Test that we can enable NACK on receive streams.
1552TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001553 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001555 cricket::AudioSendParameters parameters;
1556 parameters.codecs.push_back(kOpusCodec);
1557 parameters.codecs[0].AddFeedbackParam(
1558 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1559 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001560 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1561 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001563 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1564 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565}
1566
1567// Test that we can disable NACK.
1568TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001569 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001570 cricket::AudioSendParameters parameters;
1571 parameters.codecs.push_back(kOpusCodec);
1572 parameters.codecs[0].AddFeedbackParam(
1573 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1574 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001575 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001576 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001578 parameters.codecs.clear();
1579 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001580 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001582}
1583
1584// Test that we can disable NACK on receive streams.
1585TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001586 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001587 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 cricket::AudioSendParameters parameters;
1589 parameters.codecs.push_back(kOpusCodec);
1590 parameters.codecs[0].AddFeedbackParam(
1591 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1592 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001593 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001594 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1595 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001597 parameters.codecs.clear();
1598 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001600 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1601 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001602}
1603
1604// Test that NACK is enabled on a new receive stream.
1605TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001606 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 cricket::AudioSendParameters parameters;
1608 parameters.codecs.push_back(kIsacCodec);
1609 parameters.codecs.push_back(kCn16000Codec);
1610 parameters.codecs[0].AddFeedbackParam(
1611 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1612 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001613 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001614 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001615
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_TRUE(AddRecvStream(kSsrcY));
1617 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1618 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1619 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001620}
1621
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001622// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001623TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001624 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 cricket::AudioSendParameters parameters;
1626 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001627 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001629}
1630
1631// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001633 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001634 cricket::AudioSendParameters parameters;
1635 parameters.codecs.push_back(kOpusCodec);
1636 parameters.codecs[0].bitrate = 0;
1637 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001638 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001639 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001640}
1641
1642// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001644 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001645 cricket::AudioSendParameters parameters;
1646 parameters.codecs.push_back(kOpusCodec);
1647 parameters.codecs[0].bitrate = 0;
1648 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001649 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001650 EXPECT_TRUE(GetCodecFec(kSsrcX));
1651 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001652}
1653
1654// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001655TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001656 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001657 cricket::AudioSendParameters parameters;
1658 parameters.codecs.push_back(kOpusCodec);
1659 parameters.codecs[0].bitrate = 0;
1660 parameters.codecs[0].params["stereo"] = "1";
1661 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001662 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001663 EXPECT_TRUE(GetCodecFec(kSsrcX));
1664 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001665}
1666
1667// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001670 cricket::AudioSendParameters parameters;
1671 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001673 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001674}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001675
1676// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1677TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001678 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters parameters;
1680 parameters.codecs.push_back(kIsacCodec);
1681 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001684}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001685
1686// Test that Opus FEC status can be changed.
1687TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001692 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001693
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001695 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001696 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001697}
1698
stefanba4c0e42016-02-04 04:12:24 -08001699TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001700 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001701 cricket::AudioSendParameters send_parameters;
1702 send_parameters.codecs.push_back(kOpusCodec);
1703 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001704 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001705
1706 cricket::AudioRecvParameters recv_parameters;
1707 recv_parameters.codecs.push_back(kIsacCodec);
1708 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001709 EXPECT_TRUE(AddRecvStream(kSsrcX));
1710 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001711 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001712 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001713
ossudedfd282016-06-14 07:12:39 -07001714 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001716 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001717 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001718 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001719}
1720
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001721// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1722TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001723 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001724 cricket::AudioSendParameters parameters;
1725 parameters.codecs.push_back(kOpusCodec);
1726 parameters.codecs[0].bitrate = 0;
1727 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001729 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1730 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001731
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001732 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001733 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001734 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001735}
1736
1737// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1738TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001739 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 cricket::AudioSendParameters parameters;
1741 parameters.codecs.push_back(kOpusCodec);
1742 parameters.codecs[0].bitrate = 0;
1743 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001745 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1746 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001747
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001750 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001751}
1752
1753// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1754TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001755 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters parameters;
1757 parameters.codecs.push_back(kOpusCodec);
1758 parameters.codecs[0].bitrate = 0;
1759 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001761 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1762 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001763
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001764 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001765 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001766 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001767}
1768
1769// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1770TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001771 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001772 cricket::AudioSendParameters parameters;
1773 parameters.codecs.push_back(kOpusCodec);
1774 parameters.codecs[0].bitrate = 0;
1775 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001776 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001777 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1778 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001779
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001780 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001782 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001783}
1784
1785// Test 24000 < maxplaybackrate triggers Opus full band mode.
1786TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001787 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001788 cricket::AudioSendParameters parameters;
1789 parameters.codecs.push_back(kOpusCodec);
1790 parameters.codecs[0].bitrate = 0;
1791 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001792 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001793 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1794 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001795
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001798 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001799}
1800
1801// Test Opus that without maxplaybackrate, default playback rate is used.
1802TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001803 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001804 cricket::AudioSendParameters parameters;
1805 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001807 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001808}
1809
1810// Test the with non-Opus, maxplaybackrate has no effect.
1811TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001812 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 cricket::AudioSendParameters parameters;
1814 parameters.codecs.push_back(kIsacCodec);
1815 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001817 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001818}
1819
1820// Test maxplaybackrate can be set on two streams.
1821TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001822 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 cricket::AudioSendParameters parameters;
1824 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001826 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001827
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001828 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001829 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001830 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001831
solenberg2100c0b2017-03-01 11:29:29 -08001832 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1833 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001834}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001835
Minyue Li7100dcd2015-03-27 05:05:59 +01001836// Test that with usedtx=0, Opus DTX is off.
1837TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
1840 parameters.codecs.push_back(kOpusCodec);
1841 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001842 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001843 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001844}
1845
1846// Test that with usedtx=1, Opus DTX is on.
1847TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001848 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001849 cricket::AudioSendParameters parameters;
1850 parameters.codecs.push_back(kOpusCodec);
1851 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001852 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001853 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001854}
1855
1856// Test that usedtx=1 works with stereo Opus.
1857TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001858 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 cricket::AudioSendParameters parameters;
1860 parameters.codecs.push_back(kOpusCodec);
1861 parameters.codecs[0].params["usedtx"] = "1";
1862 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001864 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001865}
1866
1867// Test that usedtx=1 does not work with non Opus.
1868TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 cricket::AudioSendParameters parameters;
1871 parameters.codecs.push_back(kIsacCodec);
1872 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001874 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001875}
1876
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001877// Test that we can switch back and forth between Opus and ISAC with CN.
1878TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001879 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001880
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 cricket::AudioSendParameters opus_parameters;
1882 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001884 {
solenberg2100c0b2017-03-01 11:29:29 -08001885 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001886 EXPECT_EQ(111, gcodec.pltype);
1887 EXPECT_STREQ("opus", gcodec.plname);
1888 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001889
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 cricket::AudioSendParameters isac_parameters;
1891 isac_parameters.codecs.push_back(kIsacCodec);
1892 isac_parameters.codecs.push_back(kCn16000Codec);
1893 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001894 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001895 {
solenberg2100c0b2017-03-01 11:29:29 -08001896 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(103, gcodec.pltype);
1898 EXPECT_STREQ("ISAC", gcodec.plname);
1899 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900
solenberg059fb442016-10-26 05:12:24 -07001901 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001902 {
solenberg2100c0b2017-03-01 11:29:29 -08001903 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001904 EXPECT_EQ(111, gcodec.pltype);
1905 EXPECT_STREQ("opus", gcodec.plname);
1906 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907}
1908
1909// Test that we handle various ways of specifying bitrate.
1910TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001911 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001912 cricket::AudioSendParameters parameters;
1913 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001914 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001915 {
solenberg2100c0b2017-03-01 11:29:29 -08001916 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001917 EXPECT_EQ(103, gcodec.pltype);
1918 EXPECT_STREQ("ISAC", gcodec.plname);
1919 EXPECT_EQ(32000, gcodec.rate);
1920 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001921
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001922 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001923 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001924 {
solenberg2100c0b2017-03-01 11:29:29 -08001925 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001926 EXPECT_EQ(103, gcodec.pltype);
1927 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001928 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001929 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001931 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001932 {
solenberg2100c0b2017-03-01 11:29:29 -08001933 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001934 EXPECT_EQ(103, gcodec.pltype);
1935 EXPECT_STREQ("ISAC", gcodec.plname);
1936 EXPECT_EQ(28000, gcodec.rate);
1937 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001938
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001939 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001940 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001941 {
solenberg2100c0b2017-03-01 11:29:29 -08001942 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001943 EXPECT_EQ(0, gcodec.pltype);
1944 EXPECT_STREQ("PCMU", gcodec.plname);
1945 EXPECT_EQ(64000, gcodec.rate);
1946 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001947
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001948 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001949 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001950 {
solenberg2100c0b2017-03-01 11:29:29 -08001951 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001952 EXPECT_EQ(0, gcodec.pltype);
1953 EXPECT_STREQ("PCMU", gcodec.plname);
1954 EXPECT_EQ(64000, gcodec.rate);
1955 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001956
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 parameters.codecs[0] = kOpusCodec;
1958 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001960 {
solenberg2100c0b2017-03-01 11:29:29 -08001961 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001962 EXPECT_EQ(111, gcodec.pltype);
1963 EXPECT_STREQ("opus", gcodec.plname);
1964 EXPECT_EQ(32000, gcodec.rate);
1965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966}
1967
Brave Yao5225dd82015-03-26 07:39:19 +08001968// Test that we could set packet size specified in kCodecParamPTime.
1969TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001971 cricket::AudioSendParameters parameters;
1972 parameters.codecs.push_back(kOpusCodec);
1973 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001974 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001975 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001976
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001979 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001980
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001981 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001983 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001984
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001985 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1986 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001987 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001988 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001989 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001990
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001991 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1992 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001993 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001994 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001995 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001996}
1997
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001998// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001999TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002000 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 cricket::AudioSendParameters parameters;
2002 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002003}
2004
2005// Test that we can set send codecs even with telephone-event codec as the first
2006// one on the list.
2007TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002010 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 parameters.codecs.push_back(kIsacCodec);
2012 parameters.codecs.push_back(kPcmuCodec);
2013 parameters.codecs[0].id = 98; // DTMF
2014 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002015 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002016 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002017 EXPECT_EQ(96, gcodec.pltype);
2018 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002019 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002020}
2021
solenberg31642aa2016-03-14 08:00:37 -07002022// Test that payload type range is limited for telephone-event codec.
2023TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002024 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002025 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002026 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002027 parameters.codecs.push_back(kIsacCodec);
2028 parameters.codecs[0].id = 0; // DTMF
2029 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002030 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002031 EXPECT_TRUE(channel_->CanInsertDtmf());
2032 parameters.codecs[0].id = 128; // DTMF
2033 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2034 EXPECT_FALSE(channel_->CanInsertDtmf());
2035 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002036 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002037 EXPECT_TRUE(channel_->CanInsertDtmf());
2038 parameters.codecs[0].id = -1; // DTMF
2039 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2040 EXPECT_FALSE(channel_->CanInsertDtmf());
2041}
2042
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002043// Test that we can set send codecs even with CN codec as the first
2044// one on the list.
2045TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002046 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002047 cricket::AudioSendParameters parameters;
2048 parameters.codecs.push_back(kCn16000Codec);
2049 parameters.codecs.push_back(kIsacCodec);
2050 parameters.codecs.push_back(kPcmuCodec);
2051 parameters.codecs[0].id = 98; // wideband CN
2052 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002053 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002054 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002055 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2056 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2057 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2058 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059}
2060
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002061// Test that we set VAD and DTMF types correctly as caller.
2062TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002063 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002064 cricket::AudioSendParameters parameters;
2065 parameters.codecs.push_back(kIsacCodec);
2066 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002067 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002068 parameters.codecs.push_back(kCn16000Codec);
2069 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002070 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002071 parameters.codecs[0].id = 96;
2072 parameters.codecs[2].id = 97; // wideband CN
2073 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002074 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002075 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002076 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2077 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2078 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2079 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2080 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2081 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002082 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002083}
2084
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002085// Test that we set VAD and DTMF types correctly as callee.
2086TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002087 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002088 cricket::AudioSendParameters parameters;
2089 parameters.codecs.push_back(kIsacCodec);
2090 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002091 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002092 parameters.codecs.push_back(kCn16000Codec);
2093 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002094 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002095 parameters.codecs[0].id = 96;
2096 parameters.codecs[2].id = 97; // wideband CN
2097 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002098 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002099 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002100 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002101
solenberg2100c0b2017-03-01 11:29:29 -08002102 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002103 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2104 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2105 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2106 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2107 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2108 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002109 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002110}
2111
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002112// Test that we only apply VAD if we have a CN codec that matches the
2113// send codec clockrate.
2114TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002115 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002116 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002117 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002118 parameters.codecs.push_back(kIsacCodec);
2119 parameters.codecs.push_back(kCn16000Codec);
2120 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002121 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002122 {
solenberg2100c0b2017-03-01 11:29:29 -08002123 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002124 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2125 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2126 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2127 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2128 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2129 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002131 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002132 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002133 {
solenberg2100c0b2017-03-01 11:29:29 -08002134 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002135 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2136 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2137 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002138 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002139 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002140 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002141 {
solenberg2100c0b2017-03-01 11:29:29 -08002142 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002143 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2144 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2145 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2146 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2147 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2148 }
Brave Yao5225dd82015-03-26 07:39:19 +08002149 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002150 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002151 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002152 {
solenberg2100c0b2017-03-01 11:29:29 -08002153 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002154 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2155 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2156 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157}
2158
2159// Test that we perform case-insensitive matching of codec names.
2160TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002161 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002162 cricket::AudioSendParameters parameters;
2163 parameters.codecs.push_back(kIsacCodec);
2164 parameters.codecs.push_back(kPcmuCodec);
2165 parameters.codecs.push_back(kCn16000Codec);
2166 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002167 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002168 parameters.codecs[0].name = "iSaC";
2169 parameters.codecs[0].id = 96;
2170 parameters.codecs[2].id = 97; // wideband CN
2171 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002173 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002174 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2175 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2176 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2177 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2178 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2179 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002180 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181}
2182
stefanba4c0e42016-02-04 04:12:24 -08002183class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2184 public:
2185 WebRtcVoiceEngineWithSendSideBweTest()
2186 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2187};
2188
2189TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2190 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002191 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002192 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002193 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2194 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2195 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002196 extension.id);
2197 return;
2198 }
2199 }
2200 FAIL() << "Transport sequence number extension not in header-extension list.";
2201}
2202
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002203// Test support for audio level header extension.
2204TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002205 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002206}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002207TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002208 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002209}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002210
solenbergd4adce42016-11-17 06:26:52 -08002211// Test support for transport sequence number header extension.
2212TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2213 TestSetSendRtpHeaderExtensions(
2214 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002215}
solenbergd4adce42016-11-17 06:26:52 -08002216TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2217 TestSetRecvRtpHeaderExtensions(
2218 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002219}
2220
solenberg1ac56142015-10-13 03:58:19 -07002221// Test that we can create a channel and start sending on it.
2222TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002223 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002224 SetSendParameters(send_parameters_);
2225 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002226 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002227 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002228 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002229}
2230
2231// Test that a channel will send if and only if it has a source and is enabled
2232// for sending.
2233TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002234 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002236 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002237 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002238 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2239 SetAudioSend(kSsrcX, true, &fake_source_);
2240 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2241 SetAudioSend(kSsrcX, true, nullptr);
2242 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002243}
2244
solenberg94218532016-06-16 10:53:22 -07002245// Test that a channel is muted/unmuted.
2246TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2247 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002248 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002249 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2250 SetAudioSend(kSsrcX, true, nullptr);
2251 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2252 SetAudioSend(kSsrcX, false, nullptr);
2253 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002254}
2255
solenberg6d6e7c52016-04-13 09:07:30 -07002256// Test that SetSendParameters() does not alter a stream's send state.
2257TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2258 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002259 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002260
2261 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002262 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002263 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002264
2265 // Changing RTP header extensions will recreate the AudioSendStream.
2266 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002267 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002268 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002269 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002270
2271 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002272 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002274
2275 // Changing RTP header extensions will recreate the AudioSendStream.
2276 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002277 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002278 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002279}
2280
solenberg1ac56142015-10-13 03:58:19 -07002281// Test that we can create a channel and start playing out on it.
2282TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002283 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002284 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002285 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002287 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002288 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002289}
2290
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002291// Test that we can add and remove send streams.
2292TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2293 SetupForMultiSendStream();
2294
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002295 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002296 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002297
solenbergc96df772015-10-21 13:01:53 -07002298 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002299 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002300 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002301 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002302 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002303 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002304 }
tfarina5237aaf2015-11-10 23:44:30 -08002305 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002306
solenbergc96df772015-10-21 13:01:53 -07002307 // Delete the send streams.
2308 for (uint32_t ssrc : kSsrcs4) {
2309 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002310 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002311 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002312 }
solenbergc96df772015-10-21 13:01:53 -07002313 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002314}
2315
2316// Test SetSendCodecs correctly configure the codecs in all send streams.
2317TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2318 SetupForMultiSendStream();
2319
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002320 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002321 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002322 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002323 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002324 }
2325
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002326 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002327 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002328 parameters.codecs.push_back(kIsacCodec);
2329 parameters.codecs.push_back(kCn16000Codec);
2330 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002331 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002332
2333 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002334 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002335 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2336 const auto& send_codec_spec =
2337 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2338 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2339 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2340 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2341 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2342 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002343 }
2344
minyue7a973442016-10-20 03:27:12 -07002345 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002346 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002347 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002348 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002349 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2350 const auto& send_codec_spec =
2351 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2352 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2353 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2354 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2355 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002356 }
2357}
2358
2359// Test we can SetSend on all send streams correctly.
2360TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2361 SetupForMultiSendStream();
2362
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002363 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002364 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002365 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002366 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002367 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002368 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002369 }
2370
2371 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002372 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002373 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002374 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002375 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002376 }
2377
2378 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002379 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002380 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002381 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002382 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002383 }
2384}
2385
2386// Test we can set the correct statistics on all send streams.
2387TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2388 SetupForMultiSendStream();
2389
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002390 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002391 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002392 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002393 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002394 }
solenberg85a04962015-10-27 03:35:21 -07002395
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002396 // Create a receive stream to check that none of the send streams end up in
2397 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002398 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002399
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002400 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002401 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002402 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002403 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002404
solenberg85a04962015-10-27 03:35:21 -07002405 // Check stats for the added streams.
2406 {
2407 cricket::VoiceMediaInfo info;
2408 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002409
solenberg85a04962015-10-27 03:35:21 -07002410 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002411 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002412 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002413 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002414 }
hbos1acfbd22016-11-17 23:43:29 -08002415 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002416
2417 // We have added one receive stream. We should see empty stats.
2418 EXPECT_EQ(info.receivers.size(), 1u);
2419 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002420 }
solenberg1ac56142015-10-13 03:58:19 -07002421
solenberg2100c0b2017-03-01 11:29:29 -08002422 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002423 {
2424 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002425 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002426 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002427 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002428 EXPECT_EQ(0u, info.receivers.size());
2429 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002430
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002431 // Deliver a new packet - a default receive stream should be created and we
2432 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002433 {
2434 cricket::VoiceMediaInfo info;
2435 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2436 SetAudioReceiveStreamStats();
2437 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002438 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002439 EXPECT_EQ(1u, info.receivers.size());
2440 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002441 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002442 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002443}
2444
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002445// Test that we can add and remove receive streams, and do proper send/playout.
2446// We can receive on multiple streams while sending one stream.
2447TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002448 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449
solenberg1ac56142015-10-13 03:58:19 -07002450 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002451 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002452 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453
solenberg1ac56142015-10-13 03:58:19 -07002454 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002455 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002456 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002457 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002458
solenberg1ac56142015-10-13 03:58:19 -07002459 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002460 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461
2462 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002463 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2464 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2465 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466
2467 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002468 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002469 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470
2471 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002472 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002473 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2474 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475
aleloi84ef6152016-08-04 05:28:21 -07002476 // Restart playout and make sure recv streams are played out.
2477 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002478 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2479 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480
aleloi84ef6152016-08-04 05:28:21 -07002481 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002482 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2483 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484}
2485
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002487// and start sending on it.
2488TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002489 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002490 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2491 EXPECT_CALL(apm_gc_,
2492 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002493 SetSendParameters(send_parameters_);
2494 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002495 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002496 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002497 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498}
2499
wu@webrtc.org97077a32013-10-25 21:18:33 +00002500TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002501 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002502 EXPECT_CALL(adm_,
2503 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002504 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2505 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002506 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2507 send_parameters_.options.tx_agc_digital_compression_gain =
2508 rtc::Optional<uint16_t>(9);
2509 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2510 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002511 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2512 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2513 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002514 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002515
2516 // Check interaction with adjust_agc_delta. Both should be respected, for
2517 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002518 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002519 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002520 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002521}
2522
wu@webrtc.org97077a32013-10-25 21:18:33 +00002523TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002524 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002525 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2526 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002527 send_parameters_.options.recording_sample_rate =
2528 rtc::Optional<uint32_t>(48000);
2529 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002530 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002531}
2532
minyue6b825df2016-10-31 04:08:32 -07002533TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2534 EXPECT_TRUE(SetupSendStream());
2535 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2536 send_parameters_.options.audio_network_adaptor_config =
2537 rtc::Optional<std::string>("1234");
2538 SetSendParameters(send_parameters_);
2539 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002540 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002541}
2542
2543TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2544 EXPECT_TRUE(SetupSendStream());
2545 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2546 send_parameters_.options.audio_network_adaptor_config =
2547 rtc::Optional<std::string>("1234");
2548 SetSendParameters(send_parameters_);
2549 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002550 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002551 const int initial_num = call_.GetNumCreatedSendStreams();
2552 cricket::AudioOptions options;
2553 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002554 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002555 // AudioSendStream expected to be recreated.
2556 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002557 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002558}
2559
2560TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2561 EXPECT_TRUE(SetupSendStream());
2562 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2563 send_parameters_.options.audio_network_adaptor_config =
2564 rtc::Optional<std::string>("1234");
2565 SetSendParameters(send_parameters_);
2566 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002567 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002568 const int initial_num = call_.GetNumCreatedSendStreams();
2569 cricket::AudioOptions options;
2570 options.audio_network_adaptor = rtc::Optional<bool>();
2571 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2572 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002573 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002574 // AudioSendStream not expected to be recreated.
2575 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2576 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002577 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002578}
2579
michaelt6672b262017-01-11 10:17:59 -08002580class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2581 : public WebRtcVoiceEngineTestFake {
2582 public:
2583 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2584 : WebRtcVoiceEngineTestFake(
2585 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2586 "Enabled/") {}
2587};
2588
2589TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2590 EXPECT_TRUE(SetupSendStream());
2591 cricket::AudioSendParameters parameters;
2592 parameters.codecs.push_back(kOpusCodec);
2593 SetSendParameters(parameters);
2594 const int initial_num = call_.GetNumCreatedSendStreams();
2595 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2596
2597 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2598 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002599 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2600 constexpr int kMinOverheadBps =
2601 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002602 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2603
2604 constexpr int kOpusMinBitrateBps = 6000;
2605 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002606 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002607 constexpr int kOpusBitrateFbBps = 32000;
2608 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002609 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002610
2611 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2612 parameters.options.audio_network_adaptor_config =
2613 rtc::Optional<std::string>("1234");
2614 SetSendParameters(parameters);
2615
ossu11bfc532017-02-16 05:37:06 -08002616 constexpr int kMinOverheadWithAnaBps =
2617 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002618 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2619
2620 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002621 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002622
2623 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002624 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002625}
2626
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002627// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002628// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002630 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002631 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002632}
2633
2634TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2635 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002636 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002637 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002638 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002639 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002640 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002641 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002642 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002643
solenberg85a04962015-10-27 03:35:21 -07002644 // Check stats for the added streams.
2645 {
2646 cricket::VoiceMediaInfo info;
2647 EXPECT_EQ(true, channel_->GetStats(&info));
2648
2649 // We have added one send stream. We should see the stats we've set.
2650 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002651 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002652 // We have added one receive stream. We should see empty stats.
2653 EXPECT_EQ(info.receivers.size(), 1u);
2654 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2655 }
solenberg1ac56142015-10-13 03:58:19 -07002656
solenberg566ef242015-11-06 15:34:49 -08002657 // Start sending - this affects some reported stats.
2658 {
2659 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002660 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002661 EXPECT_EQ(true, channel_->GetStats(&info));
2662 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002663 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002664 }
2665
solenberg2100c0b2017-03-01 11:29:29 -08002666 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002667 {
2668 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002669 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002670 EXPECT_EQ(true, channel_->GetStats(&info));
2671 EXPECT_EQ(1u, info.senders.size());
2672 EXPECT_EQ(0u, info.receivers.size());
2673 }
solenberg1ac56142015-10-13 03:58:19 -07002674
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002675 // Deliver a new packet - a default receive stream should be created and we
2676 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002677 {
2678 cricket::VoiceMediaInfo info;
2679 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2680 SetAudioReceiveStreamStats();
2681 EXPECT_EQ(true, channel_->GetStats(&info));
2682 EXPECT_EQ(1u, info.senders.size());
2683 EXPECT_EQ(1u, info.receivers.size());
2684 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002685 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002686 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002687}
2688
2689// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002690// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002691TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002692 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002693 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2694 EXPECT_TRUE(AddRecvStream(kSsrcY));
2695 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002696}
2697
2698// Test that the local SSRC is the same on sending and receiving channels if the
2699// receive channel is created before the send channel.
2700TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002701 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002702 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002704 cricket::StreamParams::CreateLegacy(kSsrcX)));
2705 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2706 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002707}
2708
2709// Test that we can properly receive packets.
2710TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002711 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002712 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002714
2715 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2716 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717}
2718
2719// Test that we can properly receive packets on multiple streams.
2720TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002721 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002722 const uint32_t ssrc1 = 1;
2723 const uint32_t ssrc2 = 2;
2724 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002725 EXPECT_TRUE(AddRecvStream(ssrc1));
2726 EXPECT_TRUE(AddRecvStream(ssrc2));
2727 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002728 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002729 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002730 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002732 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733 }
mflodman3d7db262016-04-29 00:57:13 -07002734
2735 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2736 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2737 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2738
2739 EXPECT_EQ(s1.received_packets(), 0);
2740 EXPECT_EQ(s2.received_packets(), 0);
2741 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002742
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002743 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002744 EXPECT_EQ(s1.received_packets(), 0);
2745 EXPECT_EQ(s2.received_packets(), 0);
2746 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002747
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002749 EXPECT_EQ(s1.received_packets(), 1);
2750 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2751 EXPECT_EQ(s2.received_packets(), 0);
2752 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002753
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002755 EXPECT_EQ(s1.received_packets(), 1);
2756 EXPECT_EQ(s2.received_packets(), 1);
2757 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2758 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002759
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002761 EXPECT_EQ(s1.received_packets(), 1);
2762 EXPECT_EQ(s2.received_packets(), 1);
2763 EXPECT_EQ(s3.received_packets(), 1);
2764 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002765
mflodman3d7db262016-04-29 00:57:13 -07002766 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2767 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2768 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769}
2770
solenberg2100c0b2017-03-01 11:29:29 -08002771// Test that receiving on an unsignaled stream works (a stream is created).
2772TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
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());
solenberg2100c0b2017-03-01 11:29:29 -08002779 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2780 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002781}
2782
solenberg2100c0b2017-03-01 11:29:29 -08002783// Test that receiving N unsignaled stream works (streams will be created), and
2784// that packets are forwarded to them all.
2785TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002786 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002787 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002788 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2789
solenberg2100c0b2017-03-01 11:29:29 -08002790 constexpr uint32_t kMaxUnsignaledCount = 50;
2791
2792 // Note that SSRC = 0 is not supported.
2793 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++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
solenberg2100c0b2017-03-01 11:29:29 -08002797 // Verify we have one new stream for each loop iteration.
2798 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002799 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
solenberg2100c0b2017-03-01 11:29:29 -08002803 // Sending on the same SSRCs again should not create new streams.
2804 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++ssrc) {
2805 rtc::SetBE32(&packet[8], ssrc);
2806 DeliverPacket(packet, sizeof(packet));
2807
2808 EXPECT_EQ(kMaxUnsignaledCount, call_.GetAudioReceiveStreams().size());
2809 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2810 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2811 }
2812
2813 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2814 constexpr uint32_t kAnotherSsrc = 667;
2815 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002816 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002817
2818 const auto& streams = call_.GetAudioReceiveStreams();
2819 EXPECT_EQ(kMaxUnsignaledCount, streams.size());
2820 size_t i = 0;
2821 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledCount); ++ssrc, ++i) {
2822 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2823 EXPECT_EQ(2, streams[i]->received_packets());
2824 }
2825 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2826 EXPECT_EQ(1, streams[i]->received_packets());
2827 // Sanity check that we've checked all streams.
2828 EXPECT_EQ(kMaxUnsignaledCount, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002829}
2830
solenberg2100c0b2017-03-01 11:29:29 -08002831// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002832// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002833TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002834 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002835 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002836 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2837
2838 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002839 const uint32_t signaled_ssrc = 1;
2840 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002841 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002842 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002843 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2844 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002845 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002846
2847 // Note that the first unknown SSRC cannot be 0, because we only support
2848 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002849 const uint32_t unsignaled_ssrc = 7011;
2850 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002851 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002852 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2853 packet, sizeof(packet)));
2854 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2855
2856 DeliverPacket(packet, sizeof(packet));
2857 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2858
2859 rtc::SetBE32(&packet[8], signaled_ssrc);
2860 DeliverPacket(packet, sizeof(packet));
2861 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2862 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002863}
2864
solenberg4904fb62017-02-17 12:01:14 -08002865// Two tests to verify that adding a receive stream with the same SSRC as a
2866// previously added unsignaled stream will only recreate underlying stream
2867// objects if the stream parameters have changed.
2868TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2869 EXPECT_TRUE(SetupChannel());
2870
2871 // Spawn unsignaled stream with SSRC=1.
2872 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2873 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2874 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2875 sizeof(kPcmuFrame)));
2876
2877 // Verify that the underlying stream object in Call is not recreated when a
2878 // stream with SSRC=1 is added.
2879 const auto& streams = call_.GetAudioReceiveStreams();
2880 EXPECT_EQ(1, streams.size());
2881 int audio_receive_stream_id = streams.front()->id();
2882 EXPECT_TRUE(AddRecvStream(1));
2883 EXPECT_EQ(1, streams.size());
2884 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2885}
2886
2887TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2888 EXPECT_TRUE(SetupChannel());
2889
2890 // Spawn unsignaled stream with SSRC=1.
2891 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2892 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2893 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2894 sizeof(kPcmuFrame)));
2895
2896 // Verify that the underlying stream object in Call *is* recreated when a
2897 // stream with SSRC=1 is added, and which has changed stream parameters.
2898 const auto& streams = call_.GetAudioReceiveStreams();
2899 EXPECT_EQ(1, streams.size());
2900 int audio_receive_stream_id = streams.front()->id();
2901 cricket::StreamParams stream_params;
2902 stream_params.ssrcs.push_back(1);
2903 stream_params.sync_label = "sync_label";
2904 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2905 EXPECT_EQ(1, streams.size());
2906 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2907}
2908
solenberg0a617e22015-10-20 15:49:38 -07002909// Test that we properly handle failures to add a receive stream.
2910TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002911 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002913 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914}
2915
solenberg0a617e22015-10-20 15:49:38 -07002916// Test that we properly handle failures to add a send stream.
2917TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002918 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002919 voe_.set_fail_create_channel(true);
2920 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2921}
2922
solenberg1ac56142015-10-13 03:58:19 -07002923// Test that AddRecvStream creates new stream.
2924TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002925 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002927 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002928 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929}
2930
2931// Test that after adding a recv stream, we do not decode more codecs than
2932// those previously passed into SetRecvCodecs.
2933TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002934 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002935 cricket::AudioRecvParameters parameters;
2936 parameters.codecs.push_back(kIsacCodec);
2937 parameters.codecs.push_back(kPcmuCodec);
2938 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002939 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002940 int channel_num2 = voe_.GetLastChannel();
2941 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002942 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002943 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002944 gcodec.channels = 2;
2945 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2946}
2947
2948// Test that we properly clean up any streams that were added, even if
2949// not explicitly removed.
2950TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002951 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002952 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002953 EXPECT_TRUE(AddRecvStream(1));
2954 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002955 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2956 delete channel_;
2957 channel_ = NULL;
2958 EXPECT_EQ(0, voe_.GetNumChannels());
2959}
2960
wu@webrtc.org78187522013-10-07 23:32:02 +00002961TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002962 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002963 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002964}
2965
2966TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002967 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002968 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002969 // Manually delete channel to simulate a failure.
2970 int channel = voe_.GetLastChannel();
2971 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2972 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002973 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002974 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002975 EXPECT_NE(channel, new_channel);
2976 // The last created channel is deleted too.
2977 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002978}
2979
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002980// Test the InsertDtmf on default send stream as caller.
2981TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002982 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983}
2984
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002985// Test the InsertDtmf on default send stream as callee
2986TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002987 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002988}
2989
2990// Test the InsertDtmf on specified send stream as caller.
2991TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002992 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002993}
2994
2995// Test the InsertDtmf on specified send stream as callee.
2996TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002997 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998}
2999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003001 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003002 EXPECT_CALL(adm_,
3003 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3004 EXPECT_CALL(adm_,
3005 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3006 EXPECT_CALL(adm_,
3007 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003008
solenberg246b8172015-12-08 09:50:23 -08003009 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3010 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011
solenberg246b8172015-12-08 09:50:23 -08003012 // Nothing set in AudioOptions, so everything should be as default.
3013 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003014 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003015 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003016 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3017 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018
3019 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003020 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3021 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003022 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003023 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024
3025 // Turn echo cancellation back on, with settings, and make sure
3026 // nothing else changed.
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.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003030 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003032 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3033 // control.
solenberg76377c52017-02-21 00:54:31 -08003034 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3035 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003036 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003037 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003038
3039 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003040 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3041 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003042 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3043 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3044 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003045 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003046
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003047 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003048 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3049 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003050 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003051 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003052
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003054 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3055 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3056 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3057 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003058 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003059 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003060
3061 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003062 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3063 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3064 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3065 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003066 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3067 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003068 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069
3070 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003071 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3072 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3073 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3074 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3075 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3076 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3077 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003078 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3079 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3080 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3081 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003082 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003083 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003084
solenberg1ac56142015-10-13 03:58:19 -07003085 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003086 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3088 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3089 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3090 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3091 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3092 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003093 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003094}
3095
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003096TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003097 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003098 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003099 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003100 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003101 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003102 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003103 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003104 EXPECT_CALL(adm_,
3105 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3106 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3107 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3108 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3109 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003110
kwiberg686a8ef2016-02-26 03:00:35 -08003111 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003112 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003113 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003114 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003115 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003116 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003117
3118 // Have to add a stream to make SetSend work.
3119 cricket::StreamParams stream1;
3120 stream1.ssrcs.push_back(1);
3121 channel1->AddSendStream(stream1);
3122 cricket::StreamParams stream2;
3123 stream2.ssrcs.push_back(2);
3124 channel2->AddSendStream(stream2);
3125
3126 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003127 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003128 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3129 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3130 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003131 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3132 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3133 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3134 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3135 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003136 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003137 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003138 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003140
3141 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003142 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003143 parameters_options_no_ns.options.noise_suppression =
3144 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003145 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3146 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3147 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3148 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3149 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003150 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003151 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003152 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3153 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3154 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003155 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003156
3157 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003158 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003159 parameters_options_no_agc.options.auto_gain_control =
3160 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003161 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3162 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3163 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3164 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3165 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003166 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003167 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3168 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3169 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003170 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003171
solenberg76377c52017-02-21 00:54:31 -08003172 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3173 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3174 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3175 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3176 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003177 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003178
solenberg76377c52017-02-21 00:54:31 -08003179 EXPECT_CALL(adm_, SetAGC(true)).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(true)).WillOnce(Return(0));
3183 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003184 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003185
solenberg76377c52017-02-21 00:54:31 -08003186 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3187 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3188 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3189 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3190 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003191 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003192
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003193 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003194 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3195 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003196 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003197 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003198 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003199 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003200 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3201 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3202 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3203 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3204 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003205 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003206 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3207 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3208 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003209 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003210}
3211
wu@webrtc.orgde305012013-10-31 15:40:38 +00003212// This test verifies DSCP settings are properly applied on voice media channel.
3213TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003214 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003215 cricket::FakeNetworkInterface network_interface;
3216 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003217 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003218
solenberg059fb442016-10-26 05:12:24 -07003219 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3220 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3221
solenbergbc37fc82016-04-04 09:54:44 -07003222 channel.reset(
3223 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003224 channel->SetInterface(&network_interface);
3225 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3226 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3227
3228 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003229 channel.reset(
3230 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003231 channel->SetInterface(&network_interface);
3232 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3233
3234 // Verify that setting the option to false resets the
3235 // DiffServCodePoint.
3236 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003237 channel.reset(
3238 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003239 channel->SetInterface(&network_interface);
3240 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3241 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3242
3243 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003244}
3245
solenberg1ac56142015-10-13 03:58:19 -07003246TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003247 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003248 cricket::WebRtcVoiceMediaChannel* media_channel =
3249 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003250 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003251 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003252 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003253 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3254 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3255 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003256 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003257 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003258}
3259
solenberg1ac56142015-10-13 03:58:19 -07003260TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003261 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003262 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003263 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3264 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3265 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003266 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003267 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003268 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3269 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003270 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003271 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003272 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003274}
3275
solenberg4bac9c52015-10-09 02:32:53 -07003276TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003277 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003279 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003280 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003281 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003282 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3283 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3284 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003285}
3286
solenberg2100c0b2017-03-01 11:29:29 -08003287TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003288 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003289
3290 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003291 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3293
3294 // Should remember the volume "2" which will be set on new unsignaled streams,
3295 // and also set the gain to 2 on existing unsignaled streams.
3296 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3297 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3298
3299 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3300 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3301 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3302 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3303 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3304 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3305
3306 // Setting gain with SSRC=0 should affect all unsignaled streams.
3307 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
3308 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3309 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3310
3311 // Setting gain on an individual stream affects only that.
3312 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
3313 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3314 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003315}
3316
pbos8fc7fa72015-07-15 08:02:58 -07003317TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003318 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003319 const std::string kSyncLabel = "AvSyncLabel";
3320
solenbergff976312016-03-30 23:28:51 -07003321 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003322 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3323 sp.sync_label = kSyncLabel;
3324 // Creating two channels to make sure that sync label is set properly for both
3325 // the default voice channel and following ones.
3326 EXPECT_TRUE(channel_->AddRecvStream(sp));
3327 sp.ssrcs[0] += 1;
3328 EXPECT_TRUE(channel_->AddRecvStream(sp));
3329
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003330 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003331 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003332 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003333 << "SyncGroup should be set based on sync_label";
3334 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003335 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003336 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003337}
3338
solenberg3a941542015-11-16 07:34:50 -08003339// TODO(solenberg): Remove, once recv streams are configured through Call.
3340// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003341TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003342 // Test that setting the header extensions results in the expected state
3343 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003344 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003345 ssrcs.push_back(223);
3346 ssrcs.push_back(224);
3347
solenbergff976312016-03-30 23:28:51 -07003348 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003349 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003350 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003351 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003352 cricket::StreamParams::CreateLegacy(ssrc)));
3353 }
3354
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003355 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003356 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003357 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003358 EXPECT_NE(nullptr, s);
3359 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3360 }
3361
3362 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003363 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003364 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003365 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003366 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003367 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003368 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003369 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003370 EXPECT_NE(nullptr, s);
3371 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003372 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3373 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374 for (const auto& s_ext : s_exts) {
3375 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003376 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003377 }
3378 }
3379 }
3380 }
3381
3382 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003383 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003384 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003385 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003386 EXPECT_NE(nullptr, s);
3387 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3388 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003389}
3390
3391TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3392 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003393 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003394 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003395 static const unsigned char kRtcp[] = {
3396 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3397 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3400 };
jbaucheec21bd2016-03-20 06:15:43 -07003401 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003402
solenbergff976312016-03-30 23:28:51 -07003403 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003404 cricket::WebRtcVoiceMediaChannel* media_channel =
3405 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003406 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003407 EXPECT_TRUE(media_channel->AddRecvStream(
3408 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3409
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003410 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003411 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003412 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003413 EXPECT_EQ(0, s->received_packets());
3414 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3415 EXPECT_EQ(1, s->received_packets());
3416 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3417 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003418}
Minyue2013aec2015-05-13 14:14:42 +02003419
solenberg0a617e22015-10-20 15:49:38 -07003420// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003421// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003422TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003423 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003424 EXPECT_TRUE(AddRecvStream(kSsrcY));
3425 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003426 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003427 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3428 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3429 EXPECT_TRUE(AddRecvStream(kSsrcW));
3430 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003431}
3432
solenberg7602aab2016-11-14 11:30:07 -08003433TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3434 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003435 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003436 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003437 cricket::StreamParams::CreateLegacy(kSsrcY)));
3438 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3439 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3440 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003441 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003442 cricket::StreamParams::CreateLegacy(kSsrcW)));
3443 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3444 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003445}
stefan658910c2015-09-03 05:48:32 -07003446
deadbeef884f5852016-01-15 09:20:04 -08003447TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003448 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003449 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3450 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003451
3452 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003453 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3454 EXPECT_TRUE(AddRecvStream(kSsrcX));
3455 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003456
3457 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003458 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3459 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003460
3461 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003462 channel_->SetRawAudioSink(kSsrcX, nullptr);
3463 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003464}
3465
solenberg2100c0b2017-03-01 11:29:29 -08003466TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003467 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003468 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3469 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003470 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3471 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003472
3473 // Should be able to set a default sink even when no stream exists.
3474 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3475
solenberg2100c0b2017-03-01 11:29:29 -08003476 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3477 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003478 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003479 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003480
3481 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003482 channel_->SetRawAudioSink(kSsrc0, nullptr);
3483 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003484
3485 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003486 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3487 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003488
3489 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003490 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003491 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003492 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3493
3494 // Spawn another unsignaled stream - it should be assigned the default sink
3495 // and the previous unsignaled stream should lose it.
3496 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3497 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3498 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3499 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3500 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3501 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3502
3503 // Reset the default sink - the second unsignaled stream should lose it.
3504 channel_->SetRawAudioSink(kSsrc0, nullptr);
3505 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3506 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3507
3508 // Try setting the default sink while two streams exists.
3509 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
3510 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3511 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3512
3513 // Try setting the sink for the first unsignaled stream using its known SSRC.
3514 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
3515 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3516 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3517 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003518}
3519
skvlad7a43d252016-03-22 15:32:27 -07003520// Test that, just like the video channel, the voice channel communicates the
3521// network state to the call.
3522TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003523 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003524
3525 EXPECT_EQ(webrtc::kNetworkUp,
3526 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3527 EXPECT_EQ(webrtc::kNetworkUp,
3528 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3529
3530 channel_->OnReadyToSend(false);
3531 EXPECT_EQ(webrtc::kNetworkDown,
3532 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3533 EXPECT_EQ(webrtc::kNetworkUp,
3534 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3535
3536 channel_->OnReadyToSend(true);
3537 EXPECT_EQ(webrtc::kNetworkUp,
3538 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3539 EXPECT_EQ(webrtc::kNetworkUp,
3540 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3541}
3542
aleloi18e0b672016-10-04 02:45:47 -07003543// Test that playout is still started after changing parameters
3544TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3545 SetupRecvStream();
3546 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003547 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003548
3549 // Changing RTP header extensions will recreate the AudioReceiveStream.
3550 cricket::AudioRecvParameters parameters;
3551 parameters.extensions.push_back(
3552 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3553 channel_->SetRecvParameters(parameters);
3554
solenberg2100c0b2017-03-01 11:29:29 -08003555 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003556}
3557
stefan658910c2015-09-03 05:48:32 -07003558// Tests that the library initializes and shuts down properly.
3559TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003560 // If the VoiceEngine wants to gather available codecs early, that's fine but
3561 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003562 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003563 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003564 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003565 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003566 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003567 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3568 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003569 EXPECT_TRUE(channel != nullptr);
3570 delete channel;
solenbergff976312016-03-30 23:28:51 -07003571}
stefan658910c2015-09-03 05:48:32 -07003572
solenbergff976312016-03-30 23:28:51 -07003573// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003574TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3575 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3576 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3577 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003578 // Return 100ms just in case this function gets called. If we don't,
3579 // we could enter a tight loop since the mock would return 0.
3580 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003581 {
ossuc54071d2016-08-17 02:45:41 -07003582 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003583 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003584 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003585 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003586 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003587 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3588 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3589 EXPECT_TRUE(channel != nullptr);
3590 delete channel;
3591 }
stefan658910c2015-09-03 05:48:32 -07003592}
3593
3594// Tests that the library is configured with the codecs we want.
3595TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003596 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3597 // module.
3598
stefan658910c2015-09-03 05:48:32 -07003599 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003600#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003601 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003602 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003603#endif
3604#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003605 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003606 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003607#endif
3608#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003609 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003610 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003611#endif
3612#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003613 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003614 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003615 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003616 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003617 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003618#endif
solenberg26c8c912015-11-27 04:00:25 -08003619 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003620 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003621 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003622 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003623 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003624 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003625 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3626 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3627 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3628 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3629 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3630 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003631 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003632 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003633 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003634 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003635 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003636 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003637 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003638 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003639 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003640 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003641 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003642 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003643 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003644 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003645 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003646 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003647 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003648 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003649 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003650 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003651 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003652 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003653 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003654
stefan658910c2015-09-03 05:48:32 -07003655 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003656 // TODO(ossu): Why are the payload types of codecs with non-static payload
3657 // type assignments checked here? It shouldn't really matter.
3658 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003659 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003660 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3661 if (codec.name == "CN" && codec.clockrate == 16000) {
3662 EXPECT_EQ(105, codec.id);
3663 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3664 EXPECT_EQ(106, codec.id);
3665 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3666 EXPECT_EQ(103, codec.id);
3667 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3668 EXPECT_EQ(104, codec.id);
3669 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3670 EXPECT_EQ(9, codec.id);
3671 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3672 EXPECT_EQ(126, codec.id);
3673 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3674 // Remove these checks once both send and receive side assigns payload types
3675 // dynamically.
3676 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3677 EXPECT_EQ(113, codec.id);
3678 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3679 EXPECT_EQ(112, codec.id);
3680 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3681 EXPECT_EQ(110, codec.id);
3682 } else if (codec.name == "opus") {
3683 EXPECT_EQ(111, codec.id);
3684 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3685 EXPECT_EQ("10", codec.params.find("minptime")->second);
3686 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3687 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003688 }
3689 }
stefan658910c2015-09-03 05:48:32 -07003690}
3691
3692// Tests that VoE supports at least 32 channels
3693TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003694 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003695 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003696 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003697 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003698 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003699
3700 cricket::VoiceMediaChannel* channels[32];
3701 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003702 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003703 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3704 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003705 if (!channel)
3706 break;
stefan658910c2015-09-03 05:48:32 -07003707 channels[num_channels++] = channel;
3708 }
3709
tfarina5237aaf2015-11-10 23:44:30 -08003710 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003711 EXPECT_EQ(expected, num_channels);
3712
3713 while (num_channels > 0) {
3714 delete channels[--num_channels];
3715 }
stefan658910c2015-09-03 05:48:32 -07003716}
3717
3718// Test that we set our preferred codecs properly.
3719TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003720 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3721 // - Check that our builtin codecs are usable by Channel.
3722 // - The codecs provided by the engine is usable by Channel.
3723 // It does not check that the codecs in the RecvParameters are actually
3724 // what we sent in - though it's probably reasonable to expect so, if
3725 // SetRecvParameters returns true.
3726 // I think it will become clear once audio decoder injection is completed.
3727 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003728 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003729 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003730 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003731 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003732 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3733 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003734 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003735 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003736 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003737}
ossu9def8002017-02-09 05:14:32 -08003738
3739TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3740 std::vector<webrtc::AudioCodecSpec> specs;
3741 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3742 spec1.allow_comfort_noise = false;
3743 spec1.supports_network_adaption = true;
3744 specs.push_back(spec1);
3745 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3746 spec2.allow_comfort_noise = false;
3747 specs.push_back(spec2);
3748 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3749 {{"param1", "value1b"},
3750 {"param2", "value2"}}}));
3751 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3752 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3753
3754 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3755 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3756 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3757 .WillOnce(Return(specs));
3758
3759 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3760 auto codecs = engine.recv_codecs();
3761 EXPECT_EQ(11, codecs.size());
3762
3763 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3764 // check the actual values safely, to provide better test results.
3765 auto get_codec =
3766 [&codecs](size_t index) -> const cricket::AudioCodec& {
3767 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3768 if (codecs.size() > index)
3769 return codecs[index];
3770 return missing_codec;
3771 };
3772
3773 // Ensure the general codecs are generated first and in order.
3774 for (size_t i = 0; i != specs.size(); ++i) {
3775 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3776 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3777 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3778 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3779 }
3780
3781 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003782 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003783 auto find_codec =
3784 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3785 for (size_t i = 0; i != codecs.size(); ++i) {
3786 const cricket::AudioCodec& codec = codecs[i];
3787 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3788 codec.clockrate == format.clockrate_hz &&
3789 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003790 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003791 }
3792 }
3793 return -1;
3794 };
3795
3796 // Ensure all supplementary codecs are generated last. Their internal ordering
3797 // is not important.
3798 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3799 const int num_specs = static_cast<int>(specs.size());
3800 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3801 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3802 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3803 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3804 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3805 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3806 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3807}