blob: 4c8599008ab49dbef6ca365ad461b0759357ce90 [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);
ossu0c4b8492017-03-02 11:03:25 -08001247 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001248 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001249}
1250
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001251// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1252// to apply.
1253TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001254 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001255 cricket::AudioSendParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001258 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001259 parameters.codecs[0].id = 96;
1260 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001261 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001262 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001263 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001264 // Calling SetSendCodec again with same codec which is already set.
1265 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001266 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001267 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001268}
1269
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001270// Verify that G722 is set with 16000 samples per second to WebRTC.
1271TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001272 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 cricket::AudioSendParameters parameters;
1274 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001275 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001276 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001277 EXPECT_STREQ("G722", gcodec.plname);
1278 EXPECT_EQ(1, gcodec.channels);
1279 EXPECT_EQ(16000, gcodec.plfreq);
1280}
1281
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001282// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kOpusCodec);
1287 parameters.codecs[0].bitrate = 0;
1288 parameters.codecs[0].clockrate = 50000;
1289 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290}
1291
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001292// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001294 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001295 cricket::AudioSendParameters parameters;
1296 parameters.codecs.push_back(kOpusCodec);
1297 parameters.codecs[0].bitrate = 0;
1298 parameters.codecs[0].channels = 0;
1299 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300}
1301
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001302// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001304 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001305 cricket::AudioSendParameters parameters;
1306 parameters.codecs.push_back(kOpusCodec);
1307 parameters.codecs[0].bitrate = 0;
1308 parameters.codecs[0].channels = 0;
1309 parameters.codecs[0].params["stereo"] = "1";
1310 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311}
1312
1313// Test that if channel is 1 for opus and there's no stereo, we fail.
1314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].channels = 1;
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
1323// Test that if channel is 1 for opus and stereo=0, we fail.
1324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001325 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 cricket::AudioSendParameters parameters;
1327 parameters.codecs.push_back(kOpusCodec);
1328 parameters.codecs[0].bitrate = 0;
1329 parameters.codecs[0].channels = 1;
1330 parameters.codecs[0].params["stereo"] = "0";
1331 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
1334// Test that if channel is 1 for opus and stereo=1, we fail.
1335TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001336 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001337 cricket::AudioSendParameters parameters;
1338 parameters.codecs.push_back(kOpusCodec);
1339 parameters.codecs[0].bitrate = 0;
1340 parameters.codecs[0].channels = 1;
1341 parameters.codecs[0].params["stereo"] = "1";
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
1345// Test that with bitrate=0 and no stereo,
1346// channels and bitrate are 1 and 32000.
1347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001353 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
1356// Test that with bitrate=0 and stereo=0,
1357// channels and bitrate are 1 and 32000.
1358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001364 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001365 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001368// Test that with bitrate=invalid and stereo=0,
1369// channels and bitrate are 1 and 32000.
1370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001375 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001376 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001378 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001379
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001381 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001382 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001383}
1384
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385// Test that with bitrate=0 and stereo=1,
1386// channels and bitrate are 2 and 64000.
1387TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kOpusCodec);
1391 parameters.codecs[0].bitrate = 0;
1392 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001394 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397// Test that with bitrate=invalid and stereo=1,
1398// channels and bitrate are 2 and 64000.
1399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001404 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001407 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001408
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001410 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001411 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001412}
1413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414// Test that with bitrate=N and stereo unset,
1415// channels and bitrate are 1 and N.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001422 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423 EXPECT_EQ(111, gcodec.pltype);
1424 EXPECT_EQ(96000, gcodec.rate);
1425 EXPECT_STREQ("opus", gcodec.plname);
1426 EXPECT_EQ(1, gcodec.channels);
1427 EXPECT_EQ(48000, gcodec.plfreq);
1428}
1429
1430// Test that with bitrate=N and stereo=0,
1431// channels and bitrate are 1 and N.
1432TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001433 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001434 cricket::AudioSendParameters parameters;
1435 parameters.codecs.push_back(kOpusCodec);
1436 parameters.codecs[0].bitrate = 30000;
1437 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001439 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440}
1441
1442// Test that with bitrate=N and without any parameters,
1443// channels and bitrate are 1 and N.
1444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001449 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001450 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
1453// Test that with bitrate=N and stereo=1,
1454// channels and bitrate are 2 and N.
1455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 30000;
1460 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001462 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001465// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1466// Also test that the "maxaveragebitrate" can't be set to values outside the
1467// range of 6000 and 510000
1468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001473 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001474 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001475 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001476 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001477
1478 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001480 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001481 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001482
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001483 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001484 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001485 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001486}
1487
stefan13f1a0a2016-11-30 07:22:58 -08001488TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1489 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1490 200000);
1491}
1492
1493TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1494 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1495}
1496
1497TEST_F(WebRtcVoiceEngineTestFake,
1498 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1499 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1500}
1501
1502TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1503 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1504}
1505
1506TEST_F(WebRtcVoiceEngineTestFake,
1507 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1508 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1509 200000);
1510 send_parameters_.max_bandwidth_bps = 300000;
1511 SetSendParameters(send_parameters_);
1512 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1513 << "Setting max bitrate should keep previous min bitrate.";
1514 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1515 << "Setting max bitrate should not reset start bitrate.";
1516 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1517}
1518
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001519// Test that we can enable NACK with opus as caller.
1520TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001521 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 cricket::AudioSendParameters parameters;
1523 parameters.codecs.push_back(kOpusCodec);
1524 parameters.codecs[0].AddFeedbackParam(
1525 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1526 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001528 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001529 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001530}
1531
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001532// Test that we can enable NACK with opus as callee.
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001534 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].AddFeedbackParam(
1538 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1539 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001542 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001543 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001544
1545 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001546 cricket::StreamParams::CreateLegacy(kSsrcX)));
1547 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001548}
1549
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001550// Test that we can enable NACK on receive streams.
1551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001553 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 cricket::AudioSendParameters parameters;
1555 parameters.codecs.push_back(kOpusCodec);
1556 parameters.codecs[0].AddFeedbackParam(
1557 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1558 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001559 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1560 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001561 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001562 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1563 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
1566// Test that we can disable NACK.
1567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kOpusCodec);
1571 parameters.codecs[0].AddFeedbackParam(
1572 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1573 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 parameters.codecs.clear();
1578 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001579 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001580 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581}
1582
1583// Test that we can disable NACK on receive streams.
1584TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001585 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001586 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001587 cricket::AudioSendParameters parameters;
1588 parameters.codecs.push_back(kOpusCodec);
1589 parameters.codecs[0].AddFeedbackParam(
1590 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1591 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001593 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1594 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 parameters.codecs.clear();
1597 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001598 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1600 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601}
1602
1603// Test that NACK is enabled on a new receive stream.
1604TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001605 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters parameters;
1607 parameters.codecs.push_back(kIsacCodec);
1608 parameters.codecs.push_back(kCn16000Codec);
1609 parameters.codecs[0].AddFeedbackParam(
1610 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1611 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001613 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_TRUE(AddRecvStream(kSsrcY));
1616 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1617 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1618 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619}
1620
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001621// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001622TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001623 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 cricket::AudioSendParameters parameters;
1625 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001628}
1629
1630// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001633 cricket::AudioSendParameters parameters;
1634 parameters.codecs.push_back(kOpusCodec);
1635 parameters.codecs[0].bitrate = 0;
1636 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001638 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001639}
1640
1641// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters parameters;
1645 parameters.codecs.push_back(kOpusCodec);
1646 parameters.codecs[0].bitrate = 0;
1647 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001649 EXPECT_TRUE(GetCodecFec(kSsrcX));
1650 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001651}
1652
1653// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001654TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001655 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001656 cricket::AudioSendParameters parameters;
1657 parameters.codecs.push_back(kOpusCodec);
1658 parameters.codecs[0].bitrate = 0;
1659 parameters.codecs[0].params["stereo"] = "1";
1660 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001661 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001662 EXPECT_TRUE(GetCodecFec(kSsrcX));
1663 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001664}
1665
1666// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001667TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001668 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 cricket::AudioSendParameters parameters;
1670 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001672 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001673}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001674
1675// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters parameters;
1679 parameters.codecs.push_back(kIsacCodec);
1680 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001682 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001683}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001684
1685// Test that Opus FEC status can be changed.
1686TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 cricket::AudioSendParameters parameters;
1689 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001691 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001692
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001695 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001696}
1697
stefanba4c0e42016-02-04 04:12:24 -08001698TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001700 cricket::AudioSendParameters send_parameters;
1701 send_parameters.codecs.push_back(kOpusCodec);
1702 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001704
1705 cricket::AudioRecvParameters recv_parameters;
1706 recv_parameters.codecs.push_back(kIsacCodec);
1707 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001708 EXPECT_TRUE(AddRecvStream(kSsrcX));
1709 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001710 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001711 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001712
ossudedfd282016-06-14 07:12:39 -07001713 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001715 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001716 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001717 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001718}
1719
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001720// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1721TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001723 cricket::AudioSendParameters parameters;
1724 parameters.codecs.push_back(kOpusCodec);
1725 parameters.codecs[0].bitrate = 0;
1726 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001728 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1729 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001730
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001733 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001734}
1735
1736// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1737TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001738 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters parameters;
1740 parameters.codecs.push_back(kOpusCodec);
1741 parameters.codecs[0].bitrate = 0;
1742 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001744 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1745 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001749 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001750}
1751
1752// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1753TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001754 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001755 cricket::AudioSendParameters parameters;
1756 parameters.codecs.push_back(kOpusCodec);
1757 parameters.codecs[0].bitrate = 0;
1758 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001760 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1761 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001762
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001763 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001765 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001766}
1767
1768// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1769TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001770 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 cricket::AudioSendParameters parameters;
1772 parameters.codecs.push_back(kOpusCodec);
1773 parameters.codecs[0].bitrate = 0;
1774 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001776 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1777 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001778
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001781 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001782}
1783
1784// Test 24000 < maxplaybackrate triggers Opus full band mode.
1785TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001786 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 cricket::AudioSendParameters parameters;
1788 parameters.codecs.push_back(kOpusCodec);
1789 parameters.codecs[0].bitrate = 0;
1790 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001792 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1793 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001794
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001796 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001797 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001798}
1799
1800// Test Opus that without maxplaybackrate, default playback rate is used.
1801TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001802 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 cricket::AudioSendParameters parameters;
1804 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001805 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001806 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001807}
1808
1809// Test the with non-Opus, maxplaybackrate has no effect.
1810TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001811 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 cricket::AudioSendParameters parameters;
1813 parameters.codecs.push_back(kIsacCodec);
1814 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001816 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001817}
1818
1819// Test maxplaybackrate can be set on two streams.
1820TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001821 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 cricket::AudioSendParameters parameters;
1823 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001824 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001825 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001826
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001829 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001830
solenberg2100c0b2017-03-01 11:29:29 -08001831 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1832 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001833}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001834
Minyue Li7100dcd2015-03-27 05:05:59 +01001835// Test that with usedtx=0, Opus DTX is off.
1836TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001837 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 cricket::AudioSendParameters parameters;
1839 parameters.codecs.push_back(kOpusCodec);
1840 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001841 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001842 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001843}
1844
1845// Test that with usedtx=1, Opus DTX is on.
1846TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001847 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 cricket::AudioSendParameters parameters;
1849 parameters.codecs.push_back(kOpusCodec);
1850 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001852 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001853}
1854
1855// Test that usedtx=1 works with stereo Opus.
1856TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
1859 parameters.codecs.push_back(kOpusCodec);
1860 parameters.codecs[0].params["usedtx"] = "1";
1861 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001863 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001864}
1865
1866// Test that usedtx=1 does not work with non Opus.
1867TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001868 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 cricket::AudioSendParameters parameters;
1870 parameters.codecs.push_back(kIsacCodec);
1871 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001873 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001874}
1875
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001876// Test that we can switch back and forth between Opus and ISAC with CN.
1877TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001878 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001879
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 cricket::AudioSendParameters opus_parameters;
1881 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001882 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001883 {
solenberg2100c0b2017-03-01 11:29:29 -08001884 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001885 EXPECT_EQ(111, gcodec.pltype);
1886 EXPECT_STREQ("opus", gcodec.plname);
1887 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001888
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 cricket::AudioSendParameters isac_parameters;
1890 isac_parameters.codecs.push_back(kIsacCodec);
1891 isac_parameters.codecs.push_back(kCn16000Codec);
1892 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001894 {
solenberg2100c0b2017-03-01 11:29:29 -08001895 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(103, gcodec.pltype);
1897 EXPECT_STREQ("ISAC", gcodec.plname);
1898 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001901 {
solenberg2100c0b2017-03-01 11:29:29 -08001902 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001903 EXPECT_EQ(111, gcodec.pltype);
1904 EXPECT_STREQ("opus", gcodec.plname);
1905 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001906}
1907
1908// Test that we handle various ways of specifying bitrate.
1909TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001910 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 cricket::AudioSendParameters parameters;
1912 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001913 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001914 {
solenberg2100c0b2017-03-01 11:29:29 -08001915 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001916 EXPECT_EQ(103, gcodec.pltype);
1917 EXPECT_STREQ("ISAC", gcodec.plname);
1918 EXPECT_EQ(32000, gcodec.rate);
1919 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001922 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001923 {
solenberg2100c0b2017-03-01 11:29:29 -08001924 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001925 EXPECT_EQ(103, gcodec.pltype);
1926 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001927 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001928 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001930 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001931 {
solenberg2100c0b2017-03-01 11:29:29 -08001932 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001933 EXPECT_EQ(103, gcodec.pltype);
1934 EXPECT_STREQ("ISAC", gcodec.plname);
1935 EXPECT_EQ(28000, gcodec.rate);
1936 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001938 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001939 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001940 {
solenberg2100c0b2017-03-01 11:29:29 -08001941 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(0, gcodec.pltype);
1943 EXPECT_STREQ("PCMU", gcodec.plname);
1944 EXPECT_EQ(64000, gcodec.rate);
1945 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001946
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001948 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001949 {
solenberg2100c0b2017-03-01 11:29:29 -08001950 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001951 EXPECT_EQ(0, gcodec.pltype);
1952 EXPECT_STREQ("PCMU", gcodec.plname);
1953 EXPECT_EQ(64000, gcodec.rate);
1954 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001956 parameters.codecs[0] = kOpusCodec;
1957 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001958 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001959 {
solenberg2100c0b2017-03-01 11:29:29 -08001960 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001961 EXPECT_EQ(111, gcodec.pltype);
1962 EXPECT_STREQ("opus", gcodec.plname);
1963 EXPECT_EQ(32000, gcodec.rate);
1964 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965}
1966
Brave Yao5225dd82015-03-26 07:39:19 +08001967// Test that we could set packet size specified in kCodecParamPTime.
1968TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001969 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 cricket::AudioSendParameters parameters;
1971 parameters.codecs.push_back(kOpusCodec);
1972 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001974 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001975
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001978 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001979
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001983
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001984 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1985 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001987 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001988 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001989
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1991 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001993 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001994 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001995}
1996
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001997// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001999 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002000 cricket::AudioSendParameters parameters;
2001 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002002}
2003
2004// Test that we can set send codecs even with telephone-event codec as the first
2005// one on the list.
2006TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002007 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002008 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002009 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 parameters.codecs.push_back(kIsacCodec);
2011 parameters.codecs.push_back(kPcmuCodec);
2012 parameters.codecs[0].id = 98; // DTMF
2013 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002014 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002015 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002016 EXPECT_EQ(96, gcodec.pltype);
2017 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002018 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002019}
2020
solenberg31642aa2016-03-14 08:00:37 -07002021// Test that payload type range is limited for telephone-event codec.
2022TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002023 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002024 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002025 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002026 parameters.codecs.push_back(kIsacCodec);
2027 parameters.codecs[0].id = 0; // DTMF
2028 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002029 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002030 EXPECT_TRUE(channel_->CanInsertDtmf());
2031 parameters.codecs[0].id = 128; // DTMF
2032 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2033 EXPECT_FALSE(channel_->CanInsertDtmf());
2034 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002035 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002036 EXPECT_TRUE(channel_->CanInsertDtmf());
2037 parameters.codecs[0].id = -1; // DTMF
2038 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2039 EXPECT_FALSE(channel_->CanInsertDtmf());
2040}
2041
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002042// Test that we can set send codecs even with CN codec as the first
2043// one on the list.
2044TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002045 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002046 cricket::AudioSendParameters parameters;
2047 parameters.codecs.push_back(kCn16000Codec);
2048 parameters.codecs.push_back(kIsacCodec);
2049 parameters.codecs.push_back(kPcmuCodec);
2050 parameters.codecs[0].id = 98; // wideband CN
2051 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002052 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002053 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002054 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2055 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2056 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2057 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002058}
2059
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002060// Test that we set VAD and DTMF types correctly as caller.
2061TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002062 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002063 cricket::AudioSendParameters parameters;
2064 parameters.codecs.push_back(kIsacCodec);
2065 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002066 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002067 parameters.codecs.push_back(kCn16000Codec);
2068 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002069 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002070 parameters.codecs[0].id = 96;
2071 parameters.codecs[2].id = 97; // wideband CN
2072 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002073 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002074 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002075 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2076 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2077 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2078 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2079 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2080 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002081 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002082}
2083
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002084// Test that we set VAD and DTMF types correctly as callee.
2085TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002086 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002087 cricket::AudioSendParameters parameters;
2088 parameters.codecs.push_back(kIsacCodec);
2089 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002090 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002091 parameters.codecs.push_back(kCn16000Codec);
2092 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002093 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002094 parameters.codecs[0].id = 96;
2095 parameters.codecs[2].id = 97; // wideband CN
2096 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002097 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002098 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002099 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002100
solenberg2100c0b2017-03-01 11:29:29 -08002101 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002102 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2103 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2104 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2105 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2106 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2107 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002108 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002109}
2110
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111// Test that we only apply VAD if we have a CN codec that matches the
2112// send codec clockrate.
2113TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002114 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002115 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002116 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002117 parameters.codecs.push_back(kIsacCodec);
2118 parameters.codecs.push_back(kCn16000Codec);
2119 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002121 {
solenberg2100c0b2017-03-01 11:29:29 -08002122 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002123 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2124 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2125 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2126 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2127 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2128 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002129 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002130 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002131 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002132 {
solenberg2100c0b2017-03-01 11:29:29 -08002133 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002134 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2135 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2136 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002138 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002139 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002140 {
solenberg2100c0b2017-03-01 11:29:29 -08002141 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002142 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2143 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2144 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2145 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2146 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2147 }
Brave Yao5225dd82015-03-26 07:39:19 +08002148 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002149 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002150 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002151 {
solenberg2100c0b2017-03-01 11:29:29 -08002152 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002153 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2154 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2155 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002156}
2157
2158// Test that we perform case-insensitive matching of codec names.
2159TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002160 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 cricket::AudioSendParameters parameters;
2162 parameters.codecs.push_back(kIsacCodec);
2163 parameters.codecs.push_back(kPcmuCodec);
2164 parameters.codecs.push_back(kCn16000Codec);
2165 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002166 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 parameters.codecs[0].name = "iSaC";
2168 parameters.codecs[0].id = 96;
2169 parameters.codecs[2].id = 97; // wideband CN
2170 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002171 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002172 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002173 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2174 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2175 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2176 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2177 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2178 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002179 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180}
2181
stefanba4c0e42016-02-04 04:12:24 -08002182class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2183 public:
2184 WebRtcVoiceEngineWithSendSideBweTest()
2185 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2186};
2187
2188TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2189 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002190 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002191 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002192 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2193 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2194 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002195 extension.id);
2196 return;
2197 }
2198 }
2199 FAIL() << "Transport sequence number extension not in header-extension list.";
2200}
2201
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002202// Test support for audio level header extension.
2203TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002204 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002205}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002206TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002207 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002208}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002209
solenbergd4adce42016-11-17 06:26:52 -08002210// Test support for transport sequence number header extension.
2211TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2212 TestSetSendRtpHeaderExtensions(
2213 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002214}
solenbergd4adce42016-11-17 06:26:52 -08002215TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2216 TestSetRecvRtpHeaderExtensions(
2217 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218}
2219
solenberg1ac56142015-10-13 03:58:19 -07002220// Test that we can create a channel and start sending on it.
2221TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002222 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002223 SetSendParameters(send_parameters_);
2224 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002226 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002228}
2229
2230// Test that a channel will send if and only if it has a source and is enabled
2231// for sending.
2232TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002233 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002234 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002235 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002236 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2238 SetAudioSend(kSsrcX, true, &fake_source_);
2239 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2240 SetAudioSend(kSsrcX, true, nullptr);
2241 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002242}
2243
solenberg94218532016-06-16 10:53:22 -07002244// Test that a channel is muted/unmuted.
2245TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2246 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002247 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002248 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2249 SetAudioSend(kSsrcX, true, nullptr);
2250 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2251 SetAudioSend(kSsrcX, false, nullptr);
2252 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002253}
2254
solenberg6d6e7c52016-04-13 09:07:30 -07002255// Test that SetSendParameters() does not alter a stream's send state.
2256TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2257 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002258 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002259
2260 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002261 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002263
2264 // Changing RTP header extensions will recreate the AudioSendStream.
2265 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002266 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002267 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002268 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002269
2270 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002271 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002272 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002273
2274 // Changing RTP header extensions will recreate the AudioSendStream.
2275 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002276 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002277 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002278}
2279
solenberg1ac56142015-10-13 03:58:19 -07002280// Test that we can create a channel and start playing out on it.
2281TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002282 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002283 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002284 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002286 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288}
2289
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002290// Test that we can add and remove send streams.
2291TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2292 SetupForMultiSendStream();
2293
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002294 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002295 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002296
solenbergc96df772015-10-21 13:01:53 -07002297 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002298 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002299 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002300 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002301 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002302 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002303 }
tfarina5237aaf2015-11-10 23:44:30 -08002304 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305
solenbergc96df772015-10-21 13:01:53 -07002306 // Delete the send streams.
2307 for (uint32_t ssrc : kSsrcs4) {
2308 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002309 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002310 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002311 }
solenbergc96df772015-10-21 13:01:53 -07002312 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002313}
2314
2315// Test SetSendCodecs correctly configure the codecs in all send streams.
2316TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2317 SetupForMultiSendStream();
2318
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002319 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002320 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002321 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002322 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 }
2324
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002325 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002326 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002327 parameters.codecs.push_back(kIsacCodec);
2328 parameters.codecs.push_back(kCn16000Codec);
2329 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002330 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002331
2332 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002333 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002334 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2335 const auto& send_codec_spec =
2336 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2337 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2338 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2339 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2340 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2341 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342 }
2343
minyue7a973442016-10-20 03:27:12 -07002344 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002345 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002346 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002347 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002348 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2349 const auto& send_codec_spec =
2350 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2351 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002352 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002353 }
2354}
2355
2356// Test we can SetSend on all send streams correctly.
2357TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2358 SetupForMultiSendStream();
2359
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002360 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002361 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002362 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002363 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002364 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002365 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002366 }
2367
2368 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002369 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002370 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002371 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002372 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002373 }
2374
2375 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002376 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002377 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002378 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002379 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002380 }
2381}
2382
2383// Test we can set the correct statistics on all send streams.
2384TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2385 SetupForMultiSendStream();
2386
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002387 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002388 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002389 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002390 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 }
solenberg85a04962015-10-27 03:35:21 -07002392
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002393 // Create a receive stream to check that none of the send streams end up in
2394 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002395 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002396
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002397 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002398 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002399 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002400 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002401
solenberg85a04962015-10-27 03:35:21 -07002402 // Check stats for the added streams.
2403 {
2404 cricket::VoiceMediaInfo info;
2405 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002406
solenberg85a04962015-10-27 03:35:21 -07002407 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002408 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002409 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002410 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002411 }
hbos1acfbd22016-11-17 23:43:29 -08002412 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002413
2414 // We have added one receive stream. We should see empty stats.
2415 EXPECT_EQ(info.receivers.size(), 1u);
2416 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002417 }
solenberg1ac56142015-10-13 03:58:19 -07002418
solenberg2100c0b2017-03-01 11:29:29 -08002419 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002420 {
2421 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002422 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002423 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002424 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002425 EXPECT_EQ(0u, info.receivers.size());
2426 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002427
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002428 // Deliver a new packet - a default receive stream should be created and we
2429 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002430 {
2431 cricket::VoiceMediaInfo info;
2432 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2433 SetAudioReceiveStreamStats();
2434 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002435 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002436 EXPECT_EQ(1u, info.receivers.size());
2437 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002438 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002439 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002440}
2441
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002442// Test that we can add and remove receive streams, and do proper send/playout.
2443// We can receive on multiple streams while sending one stream.
2444TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002445 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446
solenberg1ac56142015-10-13 03:58:19 -07002447 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002448 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002449 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450
solenberg1ac56142015-10-13 03:58:19 -07002451 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002452 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002453 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002454 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455
solenberg1ac56142015-10-13 03:58:19 -07002456 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002457 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002458
2459 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002460 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2461 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2462 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463
2464 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002465 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002466 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467
2468 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002469 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002470 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2471 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472
aleloi84ef6152016-08-04 05:28:21 -07002473 // Restart playout and make sure recv streams are played out.
2474 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002475 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2476 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477
aleloi84ef6152016-08-04 05:28:21 -07002478 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2480 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481}
2482
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002484// and start sending on it.
2485TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002486 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002487 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2488 EXPECT_CALL(apm_gc_,
2489 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002490 SetSendParameters(send_parameters_);
2491 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002492 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002493 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002494 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495}
2496
wu@webrtc.org97077a32013-10-25 21:18:33 +00002497TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002498 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002499 EXPECT_CALL(adm_,
2500 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002501 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2502 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002503 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2504 send_parameters_.options.tx_agc_digital_compression_gain =
2505 rtc::Optional<uint16_t>(9);
2506 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2507 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002508 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2509 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2510 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002511 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002512
2513 // Check interaction with adjust_agc_delta. Both should be respected, for
2514 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002515 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002516 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002517 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002518}
2519
wu@webrtc.org97077a32013-10-25 21:18:33 +00002520TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002521 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002522 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2523 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002524 send_parameters_.options.recording_sample_rate =
2525 rtc::Optional<uint32_t>(48000);
2526 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002527 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002528}
2529
minyue6b825df2016-10-31 04:08:32 -07002530TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2531 EXPECT_TRUE(SetupSendStream());
2532 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2533 send_parameters_.options.audio_network_adaptor_config =
2534 rtc::Optional<std::string>("1234");
2535 SetSendParameters(send_parameters_);
2536 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002537 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002538}
2539
2540TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2541 EXPECT_TRUE(SetupSendStream());
2542 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2543 send_parameters_.options.audio_network_adaptor_config =
2544 rtc::Optional<std::string>("1234");
2545 SetSendParameters(send_parameters_);
2546 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002547 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002548 const int initial_num = call_.GetNumCreatedSendStreams();
2549 cricket::AudioOptions options;
2550 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002551 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002552 // AudioSendStream expected to be recreated.
2553 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002554 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002555}
2556
2557TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2558 EXPECT_TRUE(SetupSendStream());
2559 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2560 send_parameters_.options.audio_network_adaptor_config =
2561 rtc::Optional<std::string>("1234");
2562 SetSendParameters(send_parameters_);
2563 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002564 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002565 const int initial_num = call_.GetNumCreatedSendStreams();
2566 cricket::AudioOptions options;
2567 options.audio_network_adaptor = rtc::Optional<bool>();
2568 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2569 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002570 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002571 // AudioSendStream not expected to be recreated.
2572 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2573 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002574 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002575}
2576
michaelt6672b262017-01-11 10:17:59 -08002577class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2578 : public WebRtcVoiceEngineTestFake {
2579 public:
2580 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2581 : WebRtcVoiceEngineTestFake(
2582 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2583 "Enabled/") {}
2584};
2585
2586TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2587 EXPECT_TRUE(SetupSendStream());
2588 cricket::AudioSendParameters parameters;
2589 parameters.codecs.push_back(kOpusCodec);
2590 SetSendParameters(parameters);
2591 const int initial_num = call_.GetNumCreatedSendStreams();
2592 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2593
2594 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2595 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002596 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2597 constexpr int kMinOverheadBps =
2598 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002599 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2600
2601 constexpr int kOpusMinBitrateBps = 6000;
2602 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002603 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002604 constexpr int kOpusBitrateFbBps = 32000;
2605 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002606 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002607
2608 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2609 parameters.options.audio_network_adaptor_config =
2610 rtc::Optional<std::string>("1234");
2611 SetSendParameters(parameters);
2612
ossu11bfc532017-02-16 05:37:06 -08002613 constexpr int kMinOverheadWithAnaBps =
2614 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002615 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2616
2617 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002618 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002619
2620 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002621 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002622}
2623
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002624// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002625// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002627 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002628 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629}
2630
2631TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2632 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002633 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002634 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002635 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002636 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002637 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002638 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002639 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002640
solenberg85a04962015-10-27 03:35:21 -07002641 // Check stats for the added streams.
2642 {
2643 cricket::VoiceMediaInfo info;
2644 EXPECT_EQ(true, channel_->GetStats(&info));
2645
2646 // We have added one send stream. We should see the stats we've set.
2647 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002648 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002649 // We have added one receive stream. We should see empty stats.
2650 EXPECT_EQ(info.receivers.size(), 1u);
2651 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2652 }
solenberg1ac56142015-10-13 03:58:19 -07002653
solenberg566ef242015-11-06 15:34:49 -08002654 // Start sending - this affects some reported stats.
2655 {
2656 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002657 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002658 EXPECT_EQ(true, channel_->GetStats(&info));
2659 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002660 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002661 }
2662
solenberg2100c0b2017-03-01 11:29:29 -08002663 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002664 {
2665 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002666 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002667 EXPECT_EQ(true, channel_->GetStats(&info));
2668 EXPECT_EQ(1u, info.senders.size());
2669 EXPECT_EQ(0u, info.receivers.size());
2670 }
solenberg1ac56142015-10-13 03:58:19 -07002671
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002672 // Deliver a new packet - a default receive stream should be created and we
2673 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002674 {
2675 cricket::VoiceMediaInfo info;
2676 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2677 SetAudioReceiveStreamStats();
2678 EXPECT_EQ(true, channel_->GetStats(&info));
2679 EXPECT_EQ(1u, info.senders.size());
2680 EXPECT_EQ(1u, info.receivers.size());
2681 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002682 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002684}
2685
2686// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002687// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002689 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002690 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2691 EXPECT_TRUE(AddRecvStream(kSsrcY));
2692 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693}
2694
2695// Test that the local SSRC is the same on sending and receiving channels if the
2696// receive channel is created before the send channel.
2697TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002698 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002699 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002701 cricket::StreamParams::CreateLegacy(kSsrcX)));
2702 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2703 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704}
2705
2706// Test that we can properly receive packets.
2707TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002708 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002709 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002710 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002711
2712 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2713 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714}
2715
2716// Test that we can properly receive packets on multiple streams.
2717TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002718 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002719 const uint32_t ssrc1 = 1;
2720 const uint32_t ssrc2 = 2;
2721 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002722 EXPECT_TRUE(AddRecvStream(ssrc1));
2723 EXPECT_TRUE(AddRecvStream(ssrc2));
2724 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002726 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002727 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002728 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002729 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730 }
mflodman3d7db262016-04-29 00:57:13 -07002731
2732 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2733 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2734 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2735
2736 EXPECT_EQ(s1.received_packets(), 0);
2737 EXPECT_EQ(s2.received_packets(), 0);
2738 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002739
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002741 EXPECT_EQ(s1.received_packets(), 0);
2742 EXPECT_EQ(s2.received_packets(), 0);
2743 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002744
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002745 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002746 EXPECT_EQ(s1.received_packets(), 1);
2747 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2748 EXPECT_EQ(s2.received_packets(), 0);
2749 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002750
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002752 EXPECT_EQ(s1.received_packets(), 1);
2753 EXPECT_EQ(s2.received_packets(), 1);
2754 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2755 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002756
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002758 EXPECT_EQ(s1.received_packets(), 1);
2759 EXPECT_EQ(s2.received_packets(), 1);
2760 EXPECT_EQ(s3.received_packets(), 1);
2761 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002762
mflodman3d7db262016-04-29 00:57:13 -07002763 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2764 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2765 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766}
2767
solenberg2100c0b2017-03-01 11:29:29 -08002768// Test that receiving on an unsignaled stream works (a stream is created).
2769TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002770 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002771 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2772
solenberg7e63ef02015-11-20 00:19:43 -08002773 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002774
2775 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002776 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2777 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002778}
2779
solenberg2100c0b2017-03-01 11:29:29 -08002780// Test that receiving N unsignaled stream works (streams will be created), and
2781// that packets are forwarded to them all.
2782TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002783 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002784 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002785 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2786
solenberg2100c0b2017-03-01 11:29:29 -08002787 constexpr uint32_t kMaxUnsignaledCount = 50;
2788
2789 // Note that SSRC = 0 is not supported.
2790 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002791 rtc::SetBE32(&packet[8], ssrc);
2792 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002793
solenberg2100c0b2017-03-01 11:29:29 -08002794 // Verify we have one new stream for each loop iteration.
2795 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002796 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2797 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002798 }
mflodman3d7db262016-04-29 00:57:13 -07002799
solenberg2100c0b2017-03-01 11:29:29 -08002800 // Sending on the same SSRCs again should not create new streams.
2801 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++ssrc) {
2802 rtc::SetBE32(&packet[8], ssrc);
2803 DeliverPacket(packet, sizeof(packet));
2804
2805 EXPECT_EQ(kMaxUnsignaledCount, call_.GetAudioReceiveStreams().size());
2806 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2807 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2808 }
2809
2810 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2811 constexpr uint32_t kAnotherSsrc = 667;
2812 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002813 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002814
2815 const auto& streams = call_.GetAudioReceiveStreams();
2816 EXPECT_EQ(kMaxUnsignaledCount, streams.size());
2817 size_t i = 0;
2818 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledCount); ++ssrc, ++i) {
2819 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2820 EXPECT_EQ(2, streams[i]->received_packets());
2821 }
2822 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2823 EXPECT_EQ(1, streams[i]->received_packets());
2824 // Sanity check that we've checked all streams.
2825 EXPECT_EQ(kMaxUnsignaledCount, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002826}
2827
solenberg2100c0b2017-03-01 11:29:29 -08002828// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002829// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002830TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002831 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002832 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002833 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2834
2835 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002836 const uint32_t signaled_ssrc = 1;
2837 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002838 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002839 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002840 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2841 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002842 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002843
2844 // Note that the first unknown SSRC cannot be 0, because we only support
2845 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002846 const uint32_t unsignaled_ssrc = 7011;
2847 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002848 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002849 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2850 packet, sizeof(packet)));
2851 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2852
2853 DeliverPacket(packet, sizeof(packet));
2854 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2855
2856 rtc::SetBE32(&packet[8], signaled_ssrc);
2857 DeliverPacket(packet, sizeof(packet));
2858 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2859 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002860}
2861
solenberg4904fb62017-02-17 12:01:14 -08002862// Two tests to verify that adding a receive stream with the same SSRC as a
2863// previously added unsignaled stream will only recreate underlying stream
2864// objects if the stream parameters have changed.
2865TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2866 EXPECT_TRUE(SetupChannel());
2867
2868 // Spawn unsignaled stream with SSRC=1.
2869 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2870 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2871 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2872 sizeof(kPcmuFrame)));
2873
2874 // Verify that the underlying stream object in Call is not recreated when a
2875 // stream with SSRC=1 is added.
2876 const auto& streams = call_.GetAudioReceiveStreams();
2877 EXPECT_EQ(1, streams.size());
2878 int audio_receive_stream_id = streams.front()->id();
2879 EXPECT_TRUE(AddRecvStream(1));
2880 EXPECT_EQ(1, streams.size());
2881 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2882}
2883
2884TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2885 EXPECT_TRUE(SetupChannel());
2886
2887 // Spawn unsignaled stream with SSRC=1.
2888 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2889 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2890 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2891 sizeof(kPcmuFrame)));
2892
2893 // Verify that the underlying stream object in Call *is* recreated when a
2894 // stream with SSRC=1 is added, and which has changed stream parameters.
2895 const auto& streams = call_.GetAudioReceiveStreams();
2896 EXPECT_EQ(1, streams.size());
2897 int audio_receive_stream_id = streams.front()->id();
2898 cricket::StreamParams stream_params;
2899 stream_params.ssrcs.push_back(1);
2900 stream_params.sync_label = "sync_label";
2901 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2902 EXPECT_EQ(1, streams.size());
2903 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2904}
2905
solenberg0a617e22015-10-20 15:49:38 -07002906// Test that we properly handle failures to add a receive stream.
2907TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002908 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002909 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002910 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002911}
2912
solenberg0a617e22015-10-20 15:49:38 -07002913// Test that we properly handle failures to add a send stream.
2914TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002915 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002916 voe_.set_fail_create_channel(true);
2917 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2918}
2919
solenberg1ac56142015-10-13 03:58:19 -07002920// Test that AddRecvStream creates new stream.
2921TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002922 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002923 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002924 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002925 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926}
2927
2928// Test that after adding a recv stream, we do not decode more codecs than
2929// those previously passed into SetRecvCodecs.
2930TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002931 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 cricket::AudioRecvParameters parameters;
2933 parameters.codecs.push_back(kIsacCodec);
2934 parameters.codecs.push_back(kPcmuCodec);
2935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002936 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 int channel_num2 = voe_.GetLastChannel();
2938 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002939 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002940 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002941 gcodec.channels = 2;
2942 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2943}
2944
2945// Test that we properly clean up any streams that were added, even if
2946// not explicitly removed.
2947TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002948 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002949 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002950 EXPECT_TRUE(AddRecvStream(1));
2951 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2953 delete channel_;
2954 channel_ = NULL;
2955 EXPECT_EQ(0, voe_.GetNumChannels());
2956}
2957
wu@webrtc.org78187522013-10-07 23:32:02 +00002958TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002959 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002960 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002961}
2962
2963TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002964 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002965 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002966 // Manually delete channel to simulate a failure.
2967 int channel = voe_.GetLastChannel();
2968 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2969 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002970 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002971 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002972 EXPECT_NE(channel, new_channel);
2973 // The last created channel is deleted too.
2974 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002975}
2976
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002977// Test the InsertDtmf on default send stream as caller.
2978TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002979 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980}
2981
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002982// Test the InsertDtmf on default send stream as callee
2983TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002984 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002985}
2986
2987// Test the InsertDtmf on specified send stream as caller.
2988TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002989 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002990}
2991
2992// Test the InsertDtmf on specified send stream as callee.
2993TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002994 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995}
2996
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002998 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002999 EXPECT_CALL(adm_,
3000 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3001 EXPECT_CALL(adm_,
3002 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3003 EXPECT_CALL(adm_,
3004 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003005
solenberg246b8172015-12-08 09:50:23 -08003006 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3007 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008
solenberg246b8172015-12-08 09:50:23 -08003009 // Nothing set in AudioOptions, so everything should be as default.
3010 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003011 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003012 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003013 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3014 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015
3016 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003017 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3018 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003019 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003020 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021
3022 // Turn echo cancellation back on, with settings, and make sure
3023 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003024 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3025 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003026 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003027 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003029 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3030 // control.
solenberg76377c52017-02-21 00:54:31 -08003031 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3032 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003033 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003034 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003035
3036 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003037 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3038 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003039 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3040 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3041 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003042 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003043
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003044 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003045 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3046 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003047 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003048 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003049
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003051 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3052 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3053 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3054 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003055 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003056 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003057
3058 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003059 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3060 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3061 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3062 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003063 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3064 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003065 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066
3067 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003068 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3069 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3070 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3071 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3072 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3073 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3074 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003075 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3076 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3077 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3078 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003079 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003080 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003081
solenberg1ac56142015-10-13 03:58:19 -07003082 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003083 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3084 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3085 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3086 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3088 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3089 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003090 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003091}
3092
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003093TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003095 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003096 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003097 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003098 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003099 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003100 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003101 EXPECT_CALL(adm_,
3102 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3103 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3104 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3105 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3106 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003107
kwiberg686a8ef2016-02-26 03:00:35 -08003108 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003109 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003110 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003111 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
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())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003114
3115 // Have to add a stream to make SetSend work.
3116 cricket::StreamParams stream1;
3117 stream1.ssrcs.push_back(1);
3118 channel1->AddSendStream(stream1);
3119 cricket::StreamParams stream2;
3120 stream2.ssrcs.push_back(2);
3121 channel2->AddSendStream(stream2);
3122
3123 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003124 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003125 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3126 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3127 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003128 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3129 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3130 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3131 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3132 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003133 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003134 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003135 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003136 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003137
3138 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003140 parameters_options_no_ns.options.noise_suppression =
3141 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003142 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3143 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3144 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3145 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3146 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003147 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003148 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003149 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3150 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3151 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003152 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003153
3154 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003155 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003156 parameters_options_no_agc.options.auto_gain_control =
3157 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003158 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3159 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3160 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3161 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3162 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003163 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003164 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3165 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3166 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003167 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003168
solenberg76377c52017-02-21 00:54:31 -08003169 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3170 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3171 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3172 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3173 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003174 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003175
solenberg76377c52017-02-21 00:54:31 -08003176 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3177 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3178 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3179 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3180 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003181 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003182
solenberg76377c52017-02-21 00:54:31 -08003183 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3184 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3185 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3186 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003188 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003189
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003190 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003191 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3192 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003193 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003194 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003195 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003196 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003197 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3198 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3199 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3200 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3201 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003202 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003203 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3204 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3205 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003206 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003207}
3208
wu@webrtc.orgde305012013-10-31 15:40:38 +00003209// This test verifies DSCP settings are properly applied on voice media channel.
3210TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003211 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003212 cricket::FakeNetworkInterface network_interface;
3213 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003214 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003215
solenberg059fb442016-10-26 05:12:24 -07003216 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3217 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3218
solenbergbc37fc82016-04-04 09:54:44 -07003219 channel.reset(
3220 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003221 channel->SetInterface(&network_interface);
3222 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3223 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3224
3225 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003226 channel.reset(
3227 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003228 channel->SetInterface(&network_interface);
3229 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3230
3231 // Verify that setting the option to false resets the
3232 // DiffServCodePoint.
3233 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003234 channel.reset(
3235 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003236 channel->SetInterface(&network_interface);
3237 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3238 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3239
3240 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003241}
3242
solenberg1ac56142015-10-13 03:58:19 -07003243TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003244 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003245 cricket::WebRtcVoiceMediaChannel* media_channel =
3246 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003247 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003248 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003249 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003250 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3251 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3252 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003253 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003254 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255}
3256
solenberg1ac56142015-10-13 03:58:19 -07003257TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003258 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003259 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003260 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3261 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3262 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003263 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003264 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003265 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3266 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003267 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003268 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003269 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003271}
3272
solenberg4bac9c52015-10-09 02:32:53 -07003273TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003274 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003276 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003277 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003278 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3280 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3281 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003282}
3283
solenberg2100c0b2017-03-01 11:29:29 -08003284TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003285 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003286
3287 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003288 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003289 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3290
3291 // Should remember the volume "2" which will be set on new unsignaled streams,
3292 // and also set the gain to 2 on existing unsignaled streams.
3293 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3294 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3295
3296 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3297 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3298 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3299 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3300 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3301 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3302
3303 // Setting gain with SSRC=0 should affect all unsignaled streams.
3304 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
3305 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3306 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3307
3308 // Setting gain on an individual stream affects only that.
3309 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
3310 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3311 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003312}
3313
pbos8fc7fa72015-07-15 08:02:58 -07003314TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003315 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003316 const std::string kSyncLabel = "AvSyncLabel";
3317
solenbergff976312016-03-30 23:28:51 -07003318 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003319 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3320 sp.sync_label = kSyncLabel;
3321 // Creating two channels to make sure that sync label is set properly for both
3322 // the default voice channel and following ones.
3323 EXPECT_TRUE(channel_->AddRecvStream(sp));
3324 sp.ssrcs[0] += 1;
3325 EXPECT_TRUE(channel_->AddRecvStream(sp));
3326
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003327 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003328 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003329 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003330 << "SyncGroup should be set based on sync_label";
3331 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003332 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003333 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003334}
3335
solenberg3a941542015-11-16 07:34:50 -08003336// TODO(solenberg): Remove, once recv streams are configured through Call.
3337// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003338TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003339 // Test that setting the header extensions results in the expected state
3340 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003341 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003342 ssrcs.push_back(223);
3343 ssrcs.push_back(224);
3344
solenbergff976312016-03-30 23:28:51 -07003345 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003346 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003347 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003348 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003349 cricket::StreamParams::CreateLegacy(ssrc)));
3350 }
3351
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003352 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003353 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003354 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003355 EXPECT_NE(nullptr, s);
3356 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3357 }
3358
3359 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003360 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003361 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003362 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003363 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003364 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003365 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003366 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003367 EXPECT_NE(nullptr, s);
3368 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003369 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3370 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 for (const auto& s_ext : s_exts) {
3372 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003373 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374 }
3375 }
3376 }
3377 }
3378
3379 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003380 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003381 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003382 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003383 EXPECT_NE(nullptr, s);
3384 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3385 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003386}
3387
3388TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3389 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003390 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003391 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003392 static const unsigned char kRtcp[] = {
3393 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3394 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3397 };
jbaucheec21bd2016-03-20 06:15:43 -07003398 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003399
solenbergff976312016-03-30 23:28:51 -07003400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003401 cricket::WebRtcVoiceMediaChannel* media_channel =
3402 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003403 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003404 EXPECT_TRUE(media_channel->AddRecvStream(
3405 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3406
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003407 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003408 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003409 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003410 EXPECT_EQ(0, s->received_packets());
3411 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3412 EXPECT_EQ(1, s->received_packets());
3413 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3414 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003415}
Minyue2013aec2015-05-13 14:14:42 +02003416
solenberg0a617e22015-10-20 15:49:38 -07003417// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003418// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003419TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003420 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003421 EXPECT_TRUE(AddRecvStream(kSsrcY));
3422 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003423 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003424 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3425 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3426 EXPECT_TRUE(AddRecvStream(kSsrcW));
3427 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003428}
3429
solenberg7602aab2016-11-14 11:30:07 -08003430TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3431 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003432 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003433 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003434 cricket::StreamParams::CreateLegacy(kSsrcY)));
3435 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3436 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3437 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003438 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003439 cricket::StreamParams::CreateLegacy(kSsrcW)));
3440 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3441 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003442}
stefan658910c2015-09-03 05:48:32 -07003443
deadbeef884f5852016-01-15 09:20:04 -08003444TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003445 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003446 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3447 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003448
3449 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003450 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3451 EXPECT_TRUE(AddRecvStream(kSsrcX));
3452 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003453
3454 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003455 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3456 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003457
3458 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003459 channel_->SetRawAudioSink(kSsrcX, nullptr);
3460 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003461}
3462
solenberg2100c0b2017-03-01 11:29:29 -08003463TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003464 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003465 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3466 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003467 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3468 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003469
3470 // Should be able to set a default sink even when no stream exists.
3471 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3472
solenberg2100c0b2017-03-01 11:29:29 -08003473 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3474 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003475 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003476 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003477
3478 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003479 channel_->SetRawAudioSink(kSsrc0, nullptr);
3480 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003481
3482 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003483 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3484 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003485
3486 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003487 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003488 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003489 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3490
3491 // Spawn another unsignaled stream - it should be assigned the default sink
3492 // and the previous unsignaled stream should lose it.
3493 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3494 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3495 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3496 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3497 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3498 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3499
3500 // Reset the default sink - the second unsignaled stream should lose it.
3501 channel_->SetRawAudioSink(kSsrc0, nullptr);
3502 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3503 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3504
3505 // Try setting the default sink while two streams exists.
3506 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
3507 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3508 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3509
3510 // Try setting the sink for the first unsignaled stream using its known SSRC.
3511 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
3512 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3513 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3514 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003515}
3516
skvlad7a43d252016-03-22 15:32:27 -07003517// Test that, just like the video channel, the voice channel communicates the
3518// network state to the call.
3519TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003520 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003521
3522 EXPECT_EQ(webrtc::kNetworkUp,
3523 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3524 EXPECT_EQ(webrtc::kNetworkUp,
3525 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3526
3527 channel_->OnReadyToSend(false);
3528 EXPECT_EQ(webrtc::kNetworkDown,
3529 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3530 EXPECT_EQ(webrtc::kNetworkUp,
3531 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3532
3533 channel_->OnReadyToSend(true);
3534 EXPECT_EQ(webrtc::kNetworkUp,
3535 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3536 EXPECT_EQ(webrtc::kNetworkUp,
3537 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3538}
3539
aleloi18e0b672016-10-04 02:45:47 -07003540// Test that playout is still started after changing parameters
3541TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3542 SetupRecvStream();
3543 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003544 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003545
3546 // Changing RTP header extensions will recreate the AudioReceiveStream.
3547 cricket::AudioRecvParameters parameters;
3548 parameters.extensions.push_back(
3549 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3550 channel_->SetRecvParameters(parameters);
3551
solenberg2100c0b2017-03-01 11:29:29 -08003552 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003553}
3554
stefan658910c2015-09-03 05:48:32 -07003555// Tests that the library initializes and shuts down properly.
3556TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003557 // If the VoiceEngine wants to gather available codecs early, that's fine but
3558 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003559 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003560 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003561 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003562 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003563 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003564 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3565 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003566 EXPECT_TRUE(channel != nullptr);
3567 delete channel;
solenbergff976312016-03-30 23:28:51 -07003568}
stefan658910c2015-09-03 05:48:32 -07003569
solenbergff976312016-03-30 23:28:51 -07003570// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003571TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3572 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3573 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3574 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003575 // Return 100ms just in case this function gets called. If we don't,
3576 // we could enter a tight loop since the mock would return 0.
3577 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003578 {
ossuc54071d2016-08-17 02:45:41 -07003579 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003580 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003581 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003582 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003583 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003584 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3585 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3586 EXPECT_TRUE(channel != nullptr);
3587 delete channel;
3588 }
stefan658910c2015-09-03 05:48:32 -07003589}
3590
3591// Tests that the library is configured with the codecs we want.
3592TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003593 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3594 // module.
3595
stefan658910c2015-09-03 05:48:32 -07003596 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003597#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003598 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003599 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003600#endif
3601#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003602 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003603 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003604#endif
3605#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003606 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003607 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003608#endif
3609#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003610 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003611 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003612 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003613 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003614 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003615#endif
solenberg26c8c912015-11-27 04:00:25 -08003616 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003617 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003618 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003619 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003620 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003621 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003622 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3623 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3624 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3625 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3626 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3627 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003628 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003629 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003630 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003631 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003632 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003633 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003634 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003635 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003636 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003637 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003638 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003639 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003640 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003641 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003642 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003643 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003644 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003649 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003650 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003651
stefan658910c2015-09-03 05:48:32 -07003652 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003653 // TODO(ossu): Why are the payload types of codecs with non-static payload
3654 // type assignments checked here? It shouldn't really matter.
3655 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003656 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003657 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3658 if (codec.name == "CN" && codec.clockrate == 16000) {
3659 EXPECT_EQ(105, codec.id);
3660 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3661 EXPECT_EQ(106, codec.id);
3662 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3663 EXPECT_EQ(103, codec.id);
3664 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3665 EXPECT_EQ(104, codec.id);
3666 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3667 EXPECT_EQ(9, codec.id);
3668 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3669 EXPECT_EQ(126, codec.id);
3670 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3671 // Remove these checks once both send and receive side assigns payload types
3672 // dynamically.
3673 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3674 EXPECT_EQ(113, codec.id);
3675 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3676 EXPECT_EQ(112, codec.id);
3677 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3678 EXPECT_EQ(110, codec.id);
3679 } else if (codec.name == "opus") {
3680 EXPECT_EQ(111, codec.id);
3681 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3682 EXPECT_EQ("10", codec.params.find("minptime")->second);
3683 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3684 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003685 }
3686 }
stefan658910c2015-09-03 05:48:32 -07003687}
3688
3689// Tests that VoE supports at least 32 channels
3690TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003691 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003692 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003693 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003694 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003695 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003696
3697 cricket::VoiceMediaChannel* channels[32];
3698 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003699 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003700 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3701 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003702 if (!channel)
3703 break;
stefan658910c2015-09-03 05:48:32 -07003704 channels[num_channels++] = channel;
3705 }
3706
tfarina5237aaf2015-11-10 23:44:30 -08003707 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003708 EXPECT_EQ(expected, num_channels);
3709
3710 while (num_channels > 0) {
3711 delete channels[--num_channels];
3712 }
stefan658910c2015-09-03 05:48:32 -07003713}
3714
3715// Test that we set our preferred codecs properly.
3716TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003717 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3718 // - Check that our builtin codecs are usable by Channel.
3719 // - The codecs provided by the engine is usable by Channel.
3720 // It does not check that the codecs in the RecvParameters are actually
3721 // what we sent in - though it's probably reasonable to expect so, if
3722 // SetRecvParameters returns true.
3723 // I think it will become clear once audio decoder injection is completed.
3724 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003725 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003726 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003727 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003728 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003729 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3730 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003731 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003732 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003733 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003734}
ossu9def8002017-02-09 05:14:32 -08003735
3736TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3737 std::vector<webrtc::AudioCodecSpec> specs;
3738 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3739 spec1.allow_comfort_noise = false;
3740 spec1.supports_network_adaption = true;
3741 specs.push_back(spec1);
3742 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3743 spec2.allow_comfort_noise = false;
3744 specs.push_back(spec2);
3745 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3746 {{"param1", "value1b"},
3747 {"param2", "value2"}}}));
3748 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3749 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3750
3751 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3752 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3753 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3754 .WillOnce(Return(specs));
3755
3756 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3757 auto codecs = engine.recv_codecs();
3758 EXPECT_EQ(11, codecs.size());
3759
3760 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3761 // check the actual values safely, to provide better test results.
3762 auto get_codec =
3763 [&codecs](size_t index) -> const cricket::AudioCodec& {
3764 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3765 if (codecs.size() > index)
3766 return codecs[index];
3767 return missing_codec;
3768 };
3769
3770 // Ensure the general codecs are generated first and in order.
3771 for (size_t i = 0; i != specs.size(); ++i) {
3772 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3773 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3774 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3775 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3776 }
3777
3778 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003779 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003780 auto find_codec =
3781 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3782 for (size_t i = 0; i != codecs.size(); ++i) {
3783 const cricket::AudioCodec& codec = codecs[i];
3784 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3785 codec.clockrate == format.clockrate_hz &&
3786 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003787 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003788 }
3789 }
3790 return -1;
3791 };
3792
3793 // Ensure all supplementary codecs are generated last. Their internal ordering
3794 // is not important.
3795 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3796 const int num_specs = static_cast<int>(specs.size());
3797 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3798 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3799 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3800 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3801 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3802 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3803 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3804}