blob: 751d41b6aaca498224f0d63a46c90feda899c151 [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
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 engine, // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067 engine) { // volume
68 }
69};
skvlad11a9cbf2016-10-07 11:53:05 -070070
solenberg76377c52017-02-21 00:54:31 -080071class MockTransmitMixer : public webrtc::voe::TransmitMixer {
72 public:
73 MockTransmitMixer() = default;
74 virtual ~MockTransmitMixer() = default;
75
76 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
77};
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020078} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079
solenbergff976312016-03-30 23:28:51 -070080// Tests that our stub library "works".
81TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070082 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
83 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
84 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070085 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
86 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
87 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -080088 EXPECT_CALL(adm, SetAGC(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -070089 StrictMock<webrtc::test::MockAudioProcessing> apm;
90 EXPECT_CALL(apm, ApplyConfig(testing::_));
91 EXPECT_CALL(apm, SetExtraOptions(testing::_));
92 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -080093 StrictMock<MockTransmitMixer> transmit_mixer;
94 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
95 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -070096 EXPECT_FALSE(voe.IsInited());
97 {
ossuc54071d2016-08-17 02:45:41 -070098 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -080099 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700100 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700101 EXPECT_TRUE(voe.IsInited());
102 }
103 EXPECT_FALSE(voe.IsInited());
104}
105
deadbeef884f5852016-01-15 09:20:04 -0800106class FakeAudioSink : public webrtc::AudioSinkInterface {
107 public:
108 void OnData(const Data& audio) override {}
109};
110
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800111class FakeAudioSource : public cricket::AudioSource {
112 void SetSink(Sink* sink) override {}
113};
114
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000115class WebRtcVoiceEngineTestFake : public testing::Test {
116 public:
stefanba4c0e42016-02-04 04:12:24 -0800117 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
118
119 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800120 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
121 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
122 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700123 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800124 // AudioDeviceModule.
solenbergbc37fc82016-04-04 09:54:44 -0700125 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
126 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700127 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
128 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
129 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -0800130 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
131 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700132 EXPECT_CALL(apm_, ApplyConfig(testing::_));
133 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
134 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800135 // Default Options.
136 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
137 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
138 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
139 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
140 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
141 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
142 // Init does not overwrite default AGC config.
143 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
144 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
145 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
146 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
147 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
148 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800149 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
150 // the tests here probe the specific set of codecs provided by the builtin
151 // factory. Those tests should probably be moved elsewhere.
152 engine_.reset(new cricket::WebRtcVoiceEngine(
153 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
154 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200155 send_parameters_.codecs.push_back(kPcmuCodec);
156 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800157 // Default Options.
158 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000159 }
solenberg8189b022016-06-14 12:13:00 -0700160
solenbergff976312016-03-30 23:28:51 -0700161 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700162 EXPECT_CALL(apm_, ApplyConfig(testing::_));
163 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700164 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
165 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200166 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000167 }
solenberg8189b022016-06-14 12:13:00 -0700168
solenbergff976312016-03-30 23:28:51 -0700169 bool SetupRecvStream() {
170 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700171 return false;
172 }
solenberg2100c0b2017-03-01 11:29:29 -0800173 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700174 }
solenberg8189b022016-06-14 12:13:00 -0700175
solenbergff976312016-03-30 23:28:51 -0700176 bool SetupSendStream() {
177 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000178 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000179 }
solenberg2100c0b2017-03-01 11:29:29 -0800180 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800181 return false;
182 }
solenberg059fb442016-10-26 05:12:24 -0700183 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800184 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 }
solenberg8189b022016-06-14 12:13:00 -0700186
187 bool AddRecvStream(uint32_t ssrc) {
188 EXPECT_TRUE(channel_);
189 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
190 }
191
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000192 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700193 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700194 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800195 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
196 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700197 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800198 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000199 }
solenberg8189b022016-06-14 12:13:00 -0700200
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700202 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000203 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 }
solenberg8189b022016-06-14 12:13:00 -0700205
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200206 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 }
209
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100210 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
211 const auto* send_stream = call_.GetAudioSendStream(ssrc);
212 EXPECT_TRUE(send_stream);
213 return *send_stream;
214 }
215
deadbeef884f5852016-01-15 09:20:04 -0800216 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
217 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
218 EXPECT_TRUE(recv_stream);
219 return *recv_stream;
220 }
221
solenberg3a941542015-11-16 07:34:50 -0800222 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800223 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800224 }
225
solenberg7add0582015-11-20 09:59:34 -0800226 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800227 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800228 }
229
solenberg059fb442016-10-26 05:12:24 -0700230 void SetSend(bool enable) {
231 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700232 if (enable) {
233 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
234 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
235 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700236 EXPECT_CALL(apm_, ApplyConfig(testing::_));
237 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700238 }
solenberg059fb442016-10-26 05:12:24 -0700239 channel_->SetSend(enable);
240 }
241
242 void SetSendParameters(const cricket::AudioSendParameters& params) {
243 EXPECT_CALL(apm_, ApplyConfig(testing::_));
244 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
245 ASSERT_TRUE(channel_);
246 EXPECT_TRUE(channel_->SetSendParameters(params));
247 }
248
minyue6b825df2016-10-31 04:08:32 -0700249 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
250 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700251 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
252 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700253 if (enable && options) {
254 EXPECT_CALL(apm_, ApplyConfig(testing::_));
255 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
256 }
257 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700258 }
259
solenbergffbbcac2016-11-17 05:25:37 -0800260 void TestInsertDtmf(uint32_t ssrc, bool caller,
261 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700262 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000263 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700264 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000265 // send stream.
266 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800267 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000268 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000269
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000270 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700271 SetSendParameters(send_parameters_);
272 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800274 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800275 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700276 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000277 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000278
279 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700280 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800281 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000282 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800283 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000284 }
285
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800287 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100289 // Test send.
290 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800291 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100292 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800293 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800294 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800295 EXPECT_EQ(codec.id, telephone_event.payload_type);
296 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100297 EXPECT_EQ(2, telephone_event.event_code);
298 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299 }
300
301 // Test that send bandwidth is set correctly.
302 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000303 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
304 // |expected_result| is the expected result from SetMaxSendBandwidth().
305 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700306 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
307 int max_bitrate,
308 bool expected_result,
309 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200310 cricket::AudioSendParameters parameters;
311 parameters.codecs.push_back(codec);
312 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700313 if (expected_result) {
314 SetSendParameters(parameters);
315 } else {
316 EXPECT_FALSE(channel_->SetSendParameters(parameters));
317 }
solenberg2100c0b2017-03-01 11:29:29 -0800318 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 }
320
skvlade0d46372016-04-07 22:59:22 -0700321 // Sets the per-stream maximum bitrate limit for the specified SSRC.
322 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700323 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700324 EXPECT_EQ(1UL, parameters.encodings.size());
325
deadbeefe702b302017-02-04 12:09:01 -0800326 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700327 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700328 }
329
solenberg059fb442016-10-26 05:12:24 -0700330 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700331 cricket::AudioSendParameters send_parameters;
332 send_parameters.codecs.push_back(codec);
333 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700334 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700335 }
336
minyue7a973442016-10-20 03:27:12 -0700337 void CheckSendCodec(int32_t ssrc,
338 const char expected_name[],
339 int expected_channels,
340 int expected_bitrate) {
341 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
342 EXPECT_STREQ(expected_name, codec.plname);
343 EXPECT_EQ(expected_channels, codec.channels);
344 EXPECT_EQ(expected_bitrate, codec.rate);
345 }
346
347 int GetOpusMaxPlaybackRate(int32_t ssrc) {
348 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
349 }
350
351 bool GetOpusDtx(int32_t ssrc) {
352 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
353 }
354
355 bool GetCodecFec(int32_t ssrc) {
356 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
357 }
358
skvlade0d46372016-04-07 22:59:22 -0700359 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700360 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
361 }
362
363 int GetCodecPacSize(int32_t ssrc) {
364 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700365 }
366
minyue6b825df2016-10-31 04:08:32 -0700367 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
368 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
369 }
370
skvlade0d46372016-04-07 22:59:22 -0700371 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
372 int global_max,
373 int stream_max,
374 bool expected_result,
375 int expected_codec_bitrate) {
376 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800377 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700378
379 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700380 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800381 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700382
383 // Verify that reading back the parameters gives results
384 // consistent with the Set() result.
385 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800386 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700387 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
388 EXPECT_EQ(expected_result ? stream_max : -1,
389 resulting_parameters.encodings[0].max_bitrate_bps);
390
391 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800392 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
stefan13f1a0a2016-11-30 07:22:58 -0800395 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
396 int expected_min_bitrate_bps,
397 const char* start_bitrate_kbps,
398 int expected_start_bitrate_bps,
399 const char* max_bitrate_kbps,
400 int expected_max_bitrate_bps) {
401 EXPECT_TRUE(SetupSendStream());
402 auto& codecs = send_parameters_.codecs;
403 codecs.clear();
404 codecs.push_back(kOpusCodec);
405 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
406 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
407 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
408 SetSendParameters(send_parameters_);
409
410 EXPECT_EQ(expected_min_bitrate_bps,
411 call_.GetConfig().bitrate_config.min_bitrate_bps);
412 EXPECT_EQ(expected_start_bitrate_bps,
413 call_.GetConfig().bitrate_config.start_bitrate_bps);
414 EXPECT_EQ(expected_max_bitrate_bps,
415 call_.GetConfig().bitrate_config.max_bitrate_bps);
416 }
417
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000418 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700419 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000420
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000421 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800422 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000423
424 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700425 send_parameters_.extensions.push_back(
426 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700427 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800428 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000429
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000430 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200431 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700432 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800433 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000434
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000435 // Ensure extension is set properly.
436 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700437 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700438 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800439 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
440 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
441 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000442
solenberg7add0582015-11-20 09:59:34 -0800443 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000444 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800445 cricket::StreamParams::CreateLegacy(kSsrcY)));
446 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
447 call_.GetAudioSendStream(kSsrcY));
448 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
449 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
450 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000451
452 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200453 send_parameters_.codecs.push_back(kPcmuCodec);
454 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 }
459
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000460 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700461 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000462
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000463 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800464 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000465
466 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700467 recv_parameters_.extensions.push_back(
468 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800469 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800470 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000471
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800473 recv_parameters_.extensions.clear();
474 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800475 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000476
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000477 // Ensure extension is set properly.
478 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700479 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800480 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800481 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
482 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
483 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000484
solenberg7add0582015-11-20 09:59:34 -0800485 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800486 EXPECT_TRUE(AddRecvStream(kSsrcY));
487 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
488 call_.GetAudioReceiveStream(kSsrcY));
489 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
490 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
491 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000492
493 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800494 recv_parameters_.extensions.clear();
495 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800496 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
497 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000498 }
499
solenberg85a04962015-10-27 03:35:21 -0700500 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
501 webrtc::AudioSendStream::Stats stats;
502 stats.local_ssrc = 12;
503 stats.bytes_sent = 345;
504 stats.packets_sent = 678;
505 stats.packets_lost = 9012;
506 stats.fraction_lost = 34.56f;
507 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800508 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700509 stats.ext_seqnum = 789;
510 stats.jitter_ms = 12;
511 stats.rtt_ms = 345;
512 stats.audio_level = 678;
513 stats.aec_quality_min = 9.01f;
514 stats.echo_delay_median_ms = 234;
515 stats.echo_delay_std_ms = 567;
516 stats.echo_return_loss = 890;
517 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700518 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800519 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700520 stats.typing_noise_detected = true;
521 return stats;
522 }
523 void SetAudioSendStreamStats() {
524 for (auto* s : call_.GetAudioSendStreams()) {
525 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200526 }
solenberg85a04962015-10-27 03:35:21 -0700527 }
solenberg566ef242015-11-06 15:34:49 -0800528 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
529 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700530 const auto stats = GetAudioSendStreamStats();
531 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
532 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
533 EXPECT_EQ(info.packets_sent, stats.packets_sent);
534 EXPECT_EQ(info.packets_lost, stats.packets_lost);
535 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
536 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800537 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700538 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
539 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
540 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
541 EXPECT_EQ(info.audio_level, stats.audio_level);
542 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
543 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
544 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
545 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
546 EXPECT_EQ(info.echo_return_loss_enhancement,
547 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700548 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800549 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
550 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800551 EXPECT_EQ(info.typing_noise_detected,
552 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700553 }
554
555 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
556 webrtc::AudioReceiveStream::Stats stats;
557 stats.remote_ssrc = 123;
558 stats.bytes_rcvd = 456;
559 stats.packets_rcvd = 768;
560 stats.packets_lost = 101;
561 stats.fraction_lost = 23.45f;
562 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800563 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700564 stats.ext_seqnum = 678;
565 stats.jitter_ms = 901;
566 stats.jitter_buffer_ms = 234;
567 stats.jitter_buffer_preferred_ms = 567;
568 stats.delay_estimate_ms = 890;
569 stats.audio_level = 1234;
570 stats.expand_rate = 5.67f;
571 stats.speech_expand_rate = 8.90f;
572 stats.secondary_decoded_rate = 1.23f;
573 stats.accelerate_rate = 4.56f;
574 stats.preemptive_expand_rate = 7.89f;
575 stats.decoding_calls_to_silence_generator = 12;
576 stats.decoding_calls_to_neteq = 345;
577 stats.decoding_normal = 67890;
578 stats.decoding_plc = 1234;
579 stats.decoding_cng = 5678;
580 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700581 stats.decoding_muted_output = 3456;
582 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200583 return stats;
584 }
585 void SetAudioReceiveStreamStats() {
586 for (auto* s : call_.GetAudioReceiveStreams()) {
587 s->SetStats(GetAudioReceiveStreamStats());
588 }
589 }
590 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700591 const auto stats = GetAudioReceiveStreamStats();
592 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
593 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
594 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
595 EXPECT_EQ(info.packets_lost, stats.packets_lost);
596 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
597 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800598 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700599 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
600 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
601 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200602 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700603 stats.jitter_buffer_preferred_ms);
604 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
605 EXPECT_EQ(info.audio_level, stats.audio_level);
606 EXPECT_EQ(info.expand_rate, stats.expand_rate);
607 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
608 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
609 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
610 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200611 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700612 stats.decoding_calls_to_silence_generator);
613 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
614 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
615 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
616 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
617 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700618 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700619 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200620 }
hbos1acfbd22016-11-17 23:43:29 -0800621 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
622 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
623 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
624 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
625 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
626 codec.ToCodecParameters());
627 }
628 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
629 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
630 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
631 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
632 codec.ToCodecParameters());
633 }
634 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200635
peah8271d042016-11-22 07:24:52 -0800636 bool IsHighPassFilterEnabled() {
637 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
638 }
639
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000640 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700641 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700642 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800643 webrtc::test::MockGainControl& apm_gc_;
644 webrtc::test::MockEchoCancellation& apm_ec_;
645 webrtc::test::MockNoiseSuppression& apm_ns_;
646 webrtc::test::MockVoiceDetection& apm_vd_;
647 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700648 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200649 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700651 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700652 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200653 cricket::AudioSendParameters send_parameters_;
654 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800655 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800656 private:
657 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658};
659
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000660// Tests that we can create and destroy a channel.
661TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700662 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663}
664
solenberg31fec402016-05-06 02:13:12 -0700665// Test that we can add a send stream and that it has the correct defaults.
666TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
667 EXPECT_TRUE(SetupChannel());
668 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800669 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
670 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
671 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700672 EXPECT_EQ("", config.rtp.c_name);
673 EXPECT_EQ(0u, config.rtp.extensions.size());
674 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
675 config.send_transport);
676}
677
678// Test that we can add a receive stream and that it has the correct defaults.
679TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
680 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800681 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700682 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800683 GetRecvStreamConfig(kSsrcX);
684 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700685 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
686 EXPECT_FALSE(config.rtp.transport_cc);
687 EXPECT_EQ(0u, config.rtp.extensions.size());
688 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
689 config.rtcp_send_transport);
690 EXPECT_EQ("", config.sync_group);
691}
692
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700694// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700695// TODO(ossu): This test should move into a separate builtin audio codecs
696// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700697TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700698 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 ASSERT_FALSE(codecs.empty());
700 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
701 EXPECT_EQ(48000, codecs[0].clockrate);
702 EXPECT_EQ(2, codecs[0].channels);
703 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704}
705
stefanba4c0e42016-02-04 04:12:24 -0800706TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700707 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800708 bool opus_found = false;
709 for (cricket::AudioCodec codec : codecs) {
710 if (codec.name == "opus") {
711 EXPECT_TRUE(HasTransportCc(codec));
712 opus_found = true;
713 }
714 }
715 EXPECT_TRUE(opus_found);
716}
717
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718// Tests that we can find codecs by name or id, and that we interpret the
719// clockrate and bitrate fields properly.
720TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
721 cricket::AudioCodec codec;
722 webrtc::CodecInst codec_inst;
723 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800724 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800726 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800728 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
729 &codec_inst));
730 // Find telephone-event with explicit clockrate and 0 bitrate.
731 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800732 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 // Find ISAC with a different payload id.
734 codec = kIsacCodec;
735 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800736 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737 EXPECT_EQ(codec.id, codec_inst.pltype);
738 // Find PCMU with a 0 clockrate.
739 codec = kPcmuCodec;
740 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800741 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742 EXPECT_EQ(codec.id, codec_inst.pltype);
743 EXPECT_EQ(8000, codec_inst.plfreq);
744 // Find PCMU with a 0 bitrate.
745 codec = kPcmuCodec;
746 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800747 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000748 EXPECT_EQ(codec.id, codec_inst.pltype);
749 EXPECT_EQ(64000, codec_inst.rate);
750 // Find ISAC with an explicit bitrate.
751 codec = kIsacCodec;
752 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800753 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754 EXPECT_EQ(codec.id, codec_inst.pltype);
755 EXPECT_EQ(32000, codec_inst.rate);
756}
757
758// Test that we set our inbound codecs properly, including changing PT.
759TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700760 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200761 cricket::AudioRecvParameters parameters;
762 parameters.codecs.push_back(kIsacCodec);
763 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800764 parameters.codecs.push_back(kTelephoneEventCodec1);
765 parameters.codecs.push_back(kTelephoneEventCodec2);
766 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200767 parameters.codecs[2].id = 126;
768 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800769 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700770 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800771
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800773 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774 gcodec.plfreq = 16000;
775 gcodec.channels = 1;
776 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
777 EXPECT_EQ(106, gcodec.pltype);
778 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800779
tfarina5237aaf2015-11-10 23:44:30 -0800780 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781 gcodec.plfreq = 8000;
782 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
783 EXPECT_EQ(126, gcodec.pltype);
784 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800785
786 gcodec.plfreq = 32000;
787 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
788 EXPECT_EQ(107, gcodec.pltype);
789 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
792// Test that we fail to set an unknown inbound codec.
793TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700794 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 cricket::AudioRecvParameters parameters;
796 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700797 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799}
800
801// Test that we fail if we have duplicate types in the inbound list.
802TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700803 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200804 cricket::AudioRecvParameters parameters;
805 parameters.codecs.push_back(kIsacCodec);
806 parameters.codecs.push_back(kCn16000Codec);
807 parameters.codecs[1].id = kIsacCodec.id;
808 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that we can decode OPUS without stereo parameters.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kPcmuCodec);
817 parameters.codecs.push_back(kOpusCodec);
818 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800819 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700820 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800822 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823 // Even without stereo parameters, recv codecs still specify channels = 2.
824 EXPECT_EQ(2, opus.channels);
825 EXPECT_EQ(111, opus.pltype);
826 EXPECT_STREQ("opus", opus.plname);
827 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700828 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 EXPECT_EQ(111, opus.pltype);
830}
831
832// Test that we can decode OPUS with stereo = 0.
833TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700834 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200835 cricket::AudioRecvParameters parameters;
836 parameters.codecs.push_back(kIsacCodec);
837 parameters.codecs.push_back(kPcmuCodec);
838 parameters.codecs.push_back(kOpusCodec);
839 parameters.codecs[2].params["stereo"] = "0";
840 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800841 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842 int channel_num2 = voe_.GetLastChannel();
843 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800844 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845 // Even when stereo is off, recv codecs still specify channels = 2.
846 EXPECT_EQ(2, opus.channels);
847 EXPECT_EQ(111, opus.pltype);
848 EXPECT_STREQ("opus", opus.plname);
849 opus.pltype = 0;
850 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
851 EXPECT_EQ(111, opus.pltype);
852}
853
854// Test that we can decode OPUS with stereo = 1.
855TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700856 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 cricket::AudioRecvParameters parameters;
858 parameters.codecs.push_back(kIsacCodec);
859 parameters.codecs.push_back(kPcmuCodec);
860 parameters.codecs.push_back(kOpusCodec);
861 parameters.codecs[2].params["stereo"] = "1";
862 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800863 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864 int channel_num2 = voe_.GetLastChannel();
865 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800866 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867 EXPECT_EQ(2, opus.channels);
868 EXPECT_EQ(111, opus.pltype);
869 EXPECT_STREQ("opus", opus.plname);
870 opus.pltype = 0;
871 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
872 EXPECT_EQ(111, opus.pltype);
873}
874
875// Test that changes to recv codecs are applied to all streams.
876TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700877 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs.push_back(kTelephoneEventCodec1);
882 parameters.codecs.push_back(kTelephoneEventCodec2);
883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 parameters.codecs[2].id = 126;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800886 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800888
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800890 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891 gcodec.plfreq = 16000;
892 gcodec.channels = 1;
893 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
894 EXPECT_EQ(106, gcodec.pltype);
895 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800896
tfarina5237aaf2015-11-10 23:44:30 -0800897 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898 gcodec.plfreq = 8000;
899 gcodec.channels = 1;
900 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
901 EXPECT_EQ(126, gcodec.pltype);
902 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800903
904 gcodec.plfreq = 32000;
905 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
906 EXPECT_EQ(107, gcodec.pltype);
907 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908}
909
910TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700911 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 cricket::AudioRecvParameters parameters;
913 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800914 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
solenberg2100c0b2017-03-01 11:29:29 -0800917 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800918 ASSERT_EQ(1, dm.count(106));
919 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
922// Test that we can apply the same set of codecs again while playing.
923TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700924 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200925 cricket::AudioRecvParameters parameters;
926 parameters.codecs.push_back(kIsacCodec);
927 parameters.codecs.push_back(kCn16000Codec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700929 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931
932 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200933 parameters.codecs[0].id = 127;
934 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800935 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936}
937
938// Test that we can add a codec while playing.
939TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700940 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200941 cricket::AudioRecvParameters parameters;
942 parameters.codecs.push_back(kIsacCodec);
943 parameters.codecs.push_back(kCn16000Codec);
944 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700945 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947 parameters.codecs.push_back(kOpusCodec);
948 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800949 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800951 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
953}
954
955TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000958 // Test that when autobw is enabled, bitrate is kept as the default
959 // value. autobw is enabled for the following tests because the target
960 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
962 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
965 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700966 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700969 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970}
971
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000972TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700973 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000975 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
977 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700978 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
979 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
980 // Rates above the max (56000) should be capped.
981 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700984 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
985 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
986 // Rates above the max (510000) should be capped.
987 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988}
989
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700991 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000992
993 // Test that we can only set a maximum bitrate for a fixed-rate codec
994 // if it's bigger than the fixed rate.
995
996 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700997 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1000 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1001 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1002 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1003 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001004}
1005
1006TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001007 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008 const int kDesiredBitrate = 128000;
1009 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001010 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001011 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001012 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001013
1014 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001015 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001016
solenberg2100c0b2017-03-01 11:29:29 -08001017 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001018}
1019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020// Test that bitrate cannot be set for CBR codecs.
1021// Bitrate is ignored if it is higher than the fixed bitrate.
1022// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001023TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001024 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025
1026 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001027 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001028 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029
1030 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001031 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001032 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001033
1034 send_parameters_.max_bandwidth_bps = 128;
1035 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001036 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001037}
1038
skvlade0d46372016-04-07 22:59:22 -07001039// Test that the per-stream bitrate limit and the global
1040// bitrate limit both apply.
1041TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1042 EXPECT_TRUE(SetupSendStream());
1043
1044 // opus, default bitrate == 64000.
1045 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1046 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1047 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1048 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1049
1050 // CBR codecs allow both maximums to exceed the bitrate.
1051 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1053 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1054 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1055
1056 // CBR codecs don't allow per stream maximums to be too low.
1057 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1058 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1059}
1060
1061// Test that an attempt to set RtpParameters for a stream that does not exist
1062// fails.
1063TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1064 EXPECT_TRUE(SetupChannel());
1065 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001066 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001067 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1068
1069 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001071}
1072
1073TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001074 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001075 // This test verifies that setting RtpParameters succeeds only if
1076 // the structure contains exactly one encoding.
1077 // TODO(skvlad): Update this test when we start supporting setting parameters
1078 // for each encoding individually.
1079
1080 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001082 // Two or more encodings should result in failure.
1083 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001084 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001085 // Zero encodings should also fail.
1086 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001087 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001088}
1089
1090// Changing the SSRC through RtpParameters is not allowed.
1091TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1092 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001093 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001094 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001095 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001096}
1097
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001099// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001100TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1101 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001102 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001104 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001105 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001106 ASSERT_EQ(1u, parameters.encodings.size());
1107 ASSERT_TRUE(parameters.encodings[0].active);
1108 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001109 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1110 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001111
1112 // Now change it back to active and verify we resume sending.
1113 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001114 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1115 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001116}
1117
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001118// Test that SetRtpSendParameters configures the correct encoding channel for
1119// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001120TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1121 SetupForMultiSendStream();
1122 // Create send streams.
1123 for (uint32_t ssrc : kSsrcs4) {
1124 EXPECT_TRUE(
1125 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1126 }
1127 // Configure one stream to be limited by the stream config, another to be
1128 // limited by the global max, and the third one with no per-stream limit
1129 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001130 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001131 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1132 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1133 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1134
1135 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1136 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1137 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1138
1139 // Remove the global cap; the streams should switch to their respective
1140 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001141 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001142 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1143 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1144 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1145}
1146
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001147// Test that GetRtpSendParameters returns the currently configured codecs.
1148TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149 EXPECT_TRUE(SetupSendStream());
1150 cricket::AudioSendParameters parameters;
1151 parameters.codecs.push_back(kIsacCodec);
1152 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001153 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
solenberg2100c0b2017-03-01 11:29:29 -08001155 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1158 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001159}
1160
deadbeefcb443432016-12-12 11:12:36 -08001161// Test that GetRtpSendParameters returns an SSRC.
1162TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1163 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001164 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001165 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001166 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001167}
1168
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001169// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001170TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001171 EXPECT_TRUE(SetupSendStream());
1172 cricket::AudioSendParameters parameters;
1173 parameters.codecs.push_back(kIsacCodec);
1174 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001175 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176
solenberg2100c0b2017-03-01 11:29:29 -08001177 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001178
1179 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001180 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001181
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001182 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001183 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1184 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001185}
1186
1187// Test that GetRtpReceiveParameters returns the currently configured codecs.
1188TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1189 EXPECT_TRUE(SetupRecvStream());
1190 cricket::AudioRecvParameters parameters;
1191 parameters.codecs.push_back(kIsacCodec);
1192 parameters.codecs.push_back(kPcmuCodec);
1193 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1194
1195 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001196 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001197 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1198 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1199 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1200}
1201
deadbeefcb443432016-12-12 11:12:36 -08001202// Test that GetRtpReceiveParameters returns an SSRC.
1203TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1204 EXPECT_TRUE(SetupRecvStream());
1205 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001206 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001207 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001208 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001209}
1210
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001211// Test that if we set/get parameters multiple times, we get the same results.
1212TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1213 EXPECT_TRUE(SetupRecvStream());
1214 cricket::AudioRecvParameters parameters;
1215 parameters.codecs.push_back(kIsacCodec);
1216 parameters.codecs.push_back(kPcmuCodec);
1217 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1218
1219 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001220 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221
1222 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001223 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001224
1225 // ... And this shouldn't change the params returned by
1226 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001227 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1228 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001229}
1230
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001231// Test that we apply codecs properly.
1232TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001233 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001234 cricket::AudioSendParameters parameters;
1235 parameters.codecs.push_back(kIsacCodec);
1236 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001237 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001238 parameters.codecs[0].id = 96;
1239 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001240 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001241 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001242 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001243 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001244 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1245 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1246 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1247 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
1248 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
1249 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001250 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001251}
1252
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001253// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1254// to apply.
1255TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001256 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001257 cricket::AudioSendParameters parameters;
1258 parameters.codecs.push_back(kIsacCodec);
1259 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001260 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001261 parameters.codecs[0].id = 96;
1262 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001263 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001264 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001265 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001266 // Calling SetSendCodec again with same codec which is already set.
1267 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001268 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001269 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001270}
1271
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001272// Verify that G722 is set with 16000 samples per second to WebRTC.
1273TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001274 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001275 cricket::AudioSendParameters parameters;
1276 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001277 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001278 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001279 EXPECT_STREQ("G722", gcodec.plname);
1280 EXPECT_EQ(1, gcodec.channels);
1281 EXPECT_EQ(16000, gcodec.plfreq);
1282}
1283
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001284// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001286 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001287 cricket::AudioSendParameters parameters;
1288 parameters.codecs.push_back(kOpusCodec);
1289 parameters.codecs[0].bitrate = 0;
1290 parameters.codecs[0].clockrate = 50000;
1291 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001292}
1293
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001294// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001296 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001297 cricket::AudioSendParameters parameters;
1298 parameters.codecs.push_back(kOpusCodec);
1299 parameters.codecs[0].bitrate = 0;
1300 parameters.codecs[0].channels = 0;
1301 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001302}
1303
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001304// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001306 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 cricket::AudioSendParameters parameters;
1308 parameters.codecs.push_back(kOpusCodec);
1309 parameters.codecs[0].bitrate = 0;
1310 parameters.codecs[0].channels = 0;
1311 parameters.codecs[0].params["stereo"] = "1";
1312 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313}
1314
1315// Test that if channel is 1 for opus and there's no stereo, we fail.
1316TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001317 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001318 cricket::AudioSendParameters parameters;
1319 parameters.codecs.push_back(kOpusCodec);
1320 parameters.codecs[0].bitrate = 0;
1321 parameters.codecs[0].channels = 1;
1322 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323}
1324
1325// Test that if channel is 1 for opus and stereo=0, we fail.
1326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001327 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 cricket::AudioSendParameters parameters;
1329 parameters.codecs.push_back(kOpusCodec);
1330 parameters.codecs[0].bitrate = 0;
1331 parameters.codecs[0].channels = 1;
1332 parameters.codecs[0].params["stereo"] = "0";
1333 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334}
1335
1336// Test that if channel is 1 for opus and stereo=1, we fail.
1337TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001338 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 cricket::AudioSendParameters parameters;
1340 parameters.codecs.push_back(kOpusCodec);
1341 parameters.codecs[0].bitrate = 0;
1342 parameters.codecs[0].channels = 1;
1343 parameters.codecs[0].params["stereo"] = "1";
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
1347// Test that with bitrate=0 and no stereo,
1348// channels and bitrate are 1 and 32000.
1349TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001350 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 cricket::AudioSendParameters parameters;
1352 parameters.codecs.push_back(kOpusCodec);
1353 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001354 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001355 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
1358// Test that with bitrate=0 and stereo=0,
1359// channels and bitrate are 1 and 32000.
1360TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001361 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 cricket::AudioSendParameters parameters;
1363 parameters.codecs.push_back(kOpusCodec);
1364 parameters.codecs[0].bitrate = 0;
1365 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001366 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001367 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368}
1369
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001370// Test that with bitrate=invalid and stereo=0,
1371// channels and bitrate are 1 and 32000.
1372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001377 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001379 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001380 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001381
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001383 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001384 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001385}
1386
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387// Test that with bitrate=0 and stereo=1,
1388// channels and bitrate are 2 and 64000.
1389TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001390 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 cricket::AudioSendParameters parameters;
1392 parameters.codecs.push_back(kOpusCodec);
1393 parameters.codecs[0].bitrate = 0;
1394 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001396 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397}
1398
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001399// Test that with bitrate=invalid and stereo=1,
1400// channels and bitrate are 2 and 64000.
1401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001406 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001408 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001409 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001412 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001413 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001414}
1415
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416// Test that with bitrate=N and stereo unset,
1417// channels and bitrate are 1 and N.
1418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001424 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425 EXPECT_EQ(111, gcodec.pltype);
1426 EXPECT_EQ(96000, gcodec.rate);
1427 EXPECT_STREQ("opus", gcodec.plname);
1428 EXPECT_EQ(1, gcodec.channels);
1429 EXPECT_EQ(48000, gcodec.plfreq);
1430}
1431
1432// Test that with bitrate=N and stereo=0,
1433// channels and bitrate are 1 and N.
1434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kOpusCodec);
1438 parameters.codecs[0].bitrate = 30000;
1439 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001440 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001441 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001442}
1443
1444// Test that with bitrate=N and without any parameters,
1445// channels and bitrate are 1 and N.
1446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 cricket::AudioSendParameters parameters;
1449 parameters.codecs.push_back(kOpusCodec);
1450 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001451 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001452 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453}
1454
1455// Test that with bitrate=N and stereo=1,
1456// channels and bitrate are 2 and N.
1457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001458 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 cricket::AudioSendParameters parameters;
1460 parameters.codecs.push_back(kOpusCodec);
1461 parameters.codecs[0].bitrate = 30000;
1462 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001463 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001464 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465}
1466
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001467// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1468// Also test that the "maxaveragebitrate" can't be set to values outside the
1469// range of 6000 and 510000
1470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001475 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001478 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001479
1480 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001483 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001487 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001488}
1489
stefan13f1a0a2016-11-30 07:22:58 -08001490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1491 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1492 200000);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1496 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1497}
1498
1499TEST_F(WebRtcVoiceEngineTestFake,
1500 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1501 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1505 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1506}
1507
1508TEST_F(WebRtcVoiceEngineTestFake,
1509 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1510 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1511 200000);
1512 send_parameters_.max_bandwidth_bps = 300000;
1513 SetSendParameters(send_parameters_);
1514 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1515 << "Setting max bitrate should keep previous min bitrate.";
1516 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1517 << "Setting max bitrate should not reset start bitrate.";
1518 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1519}
1520
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001521// Test that we can enable NACK with opus as caller.
1522TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001523 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001524 cricket::AudioSendParameters parameters;
1525 parameters.codecs.push_back(kOpusCodec);
1526 parameters.codecs[0].AddFeedbackParam(
1527 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1528 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001529 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001531 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532}
1533
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001534// Test that we can enable NACK with opus as callee.
1535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].AddFeedbackParam(
1540 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1541 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001544 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001545 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001546
1547 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001548 cricket::StreamParams::CreateLegacy(kSsrcX)));
1549 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001550}
1551
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552// Test that we can enable NACK on receive streams.
1553TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001554 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kOpusCodec);
1558 parameters.codecs[0].AddFeedbackParam(
1559 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1560 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1562 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1565 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566}
1567
1568// Test that we can disable NACK.
1569TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001570 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 cricket::AudioSendParameters parameters;
1572 parameters.codecs.push_back(kOpusCodec);
1573 parameters.codecs[0].AddFeedbackParam(
1574 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1575 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001579 parameters.codecs.clear();
1580 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001581 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
1585// Test that we can disable NACK on receive streams.
1586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001587 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 cricket::AudioSendParameters parameters;
1590 parameters.codecs.push_back(kOpusCodec);
1591 parameters.codecs[0].AddFeedbackParam(
1592 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1593 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001594 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001595 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1596 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 parameters.codecs.clear();
1599 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001600 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1602 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603}
1604
1605// Test that NACK is enabled on a new receive stream.
1606TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 cricket::AudioSendParameters parameters;
1609 parameters.codecs.push_back(kIsacCodec);
1610 parameters.codecs.push_back(kCn16000Codec);
1611 parameters.codecs[0].AddFeedbackParam(
1612 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1613 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001614 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616
solenberg2100c0b2017-03-01 11:29:29 -08001617 EXPECT_TRUE(AddRecvStream(kSsrcY));
1618 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1619 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1620 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621}
1622
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001623// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001625 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001626 cricket::AudioSendParameters parameters;
1627 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001628 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001629 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001630}
1631
1632// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001633TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001634 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kOpusCodec);
1637 parameters.codecs[0].bitrate = 0;
1638 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001639 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001640 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001641}
1642
1643// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters parameters;
1647 parameters.codecs.push_back(kOpusCodec);
1648 parameters.codecs[0].bitrate = 0;
1649 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001650 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001651 EXPECT_TRUE(GetCodecFec(kSsrcX));
1652 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001653}
1654
1655// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001656TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001657 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters parameters;
1659 parameters.codecs.push_back(kOpusCodec);
1660 parameters.codecs[0].bitrate = 0;
1661 parameters.codecs[0].params["stereo"] = "1";
1662 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001663 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001664 EXPECT_TRUE(GetCodecFec(kSsrcX));
1665 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001666}
1667
1668// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001669TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001670 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001674 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001675}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001676
1677// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1678TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001679 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 cricket::AudioSendParameters parameters;
1681 parameters.codecs.push_back(kIsacCodec);
1682 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001684 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001685}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001686
1687// Test that Opus FEC status can be changed.
1688TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001689 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001690 cricket::AudioSendParameters parameters;
1691 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001694
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001698}
1699
stefanba4c0e42016-02-04 04:12:24 -08001700TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001701 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001702 cricket::AudioSendParameters send_parameters;
1703 send_parameters.codecs.push_back(kOpusCodec);
1704 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001706
1707 cricket::AudioRecvParameters recv_parameters;
1708 recv_parameters.codecs.push_back(kIsacCodec);
1709 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001710 EXPECT_TRUE(AddRecvStream(kSsrcX));
1711 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001712 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001713 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001714
ossudedfd282016-06-14 07:12:39 -07001715 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001717 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001718 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001719 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001720}
1721
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001722// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1723TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001725 cricket::AudioSendParameters parameters;
1726 parameters.codecs.push_back(kOpusCodec);
1727 parameters.codecs[0].bitrate = 0;
1728 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001730 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1731 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001732
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001733 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001735 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001736}
1737
1738// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1739TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001740 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001741 cricket::AudioSendParameters parameters;
1742 parameters.codecs.push_back(kOpusCodec);
1743 parameters.codecs[0].bitrate = 0;
1744 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001746 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1747 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001748
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001751 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001752}
1753
1754// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1755TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001756 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters parameters;
1758 parameters.codecs.push_back(kOpusCodec);
1759 parameters.codecs[0].bitrate = 0;
1760 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001761 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001762 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1763 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001764
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001766 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001767 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001768}
1769
1770// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1771TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001772 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001773 cricket::AudioSendParameters parameters;
1774 parameters.codecs.push_back(kOpusCodec);
1775 parameters.codecs[0].bitrate = 0;
1776 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001778 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1779 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001780
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001781 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001783 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001784}
1785
1786// Test 24000 < maxplaybackrate triggers Opus full band mode.
1787TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001788 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001789 cricket::AudioSendParameters parameters;
1790 parameters.codecs.push_back(kOpusCodec);
1791 parameters.codecs[0].bitrate = 0;
1792 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001794 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1795 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001796
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001799 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001800}
1801
1802// Test Opus that without maxplaybackrate, default playback rate is used.
1803TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001804 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 cricket::AudioSendParameters parameters;
1806 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001808 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001809}
1810
1811// Test the with non-Opus, maxplaybackrate has no effect.
1812TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001813 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 cricket::AudioSendParameters parameters;
1815 parameters.codecs.push_back(kIsacCodec);
1816 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001818 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001819}
1820
1821// Test maxplaybackrate can be set on two streams.
1822TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001823 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 cricket::AudioSendParameters parameters;
1825 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001827 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001828
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001831 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001832
solenberg2100c0b2017-03-01 11:29:29 -08001833 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1834 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001835}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001836
Minyue Li7100dcd2015-03-27 05:05:59 +01001837// Test that with usedtx=0, Opus DTX is off.
1838TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 cricket::AudioSendParameters parameters;
1841 parameters.codecs.push_back(kOpusCodec);
1842 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001843 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001844 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001845}
1846
1847// Test that with usedtx=1, Opus DTX is on.
1848TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001849 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001850 cricket::AudioSendParameters parameters;
1851 parameters.codecs.push_back(kOpusCodec);
1852 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001854 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001855}
1856
1857// Test that usedtx=1 works with stereo Opus.
1858TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001859 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 cricket::AudioSendParameters parameters;
1861 parameters.codecs.push_back(kOpusCodec);
1862 parameters.codecs[0].params["usedtx"] = "1";
1863 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001865 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001866}
1867
1868// Test that usedtx=1 does not work with non Opus.
1869TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001870 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 cricket::AudioSendParameters parameters;
1872 parameters.codecs.push_back(kIsacCodec);
1873 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001875 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001876}
1877
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001878// Test that we can switch back and forth between Opus and ISAC with CN.
1879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001881
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters opus_parameters;
1883 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001884 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001885 {
solenberg2100c0b2017-03-01 11:29:29 -08001886 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001887 EXPECT_EQ(111, gcodec.pltype);
1888 EXPECT_STREQ("opus", gcodec.plname);
1889 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 cricket::AudioSendParameters isac_parameters;
1892 isac_parameters.codecs.push_back(kIsacCodec);
1893 isac_parameters.codecs.push_back(kCn16000Codec);
1894 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001895 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001896 {
solenberg2100c0b2017-03-01 11:29:29 -08001897 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001898 EXPECT_EQ(103, gcodec.pltype);
1899 EXPECT_STREQ("ISAC", gcodec.plname);
1900 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901
solenberg059fb442016-10-26 05:12:24 -07001902 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001903 {
solenberg2100c0b2017-03-01 11:29:29 -08001904 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(111, gcodec.pltype);
1906 EXPECT_STREQ("opus", gcodec.plname);
1907 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001908}
1909
1910// Test that we handle various ways of specifying bitrate.
1911TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001912 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001913 cricket::AudioSendParameters parameters;
1914 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001916 {
solenberg2100c0b2017-03-01 11:29:29 -08001917 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001918 EXPECT_EQ(103, gcodec.pltype);
1919 EXPECT_STREQ("ISAC", gcodec.plname);
1920 EXPECT_EQ(32000, gcodec.rate);
1921 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001922
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001924 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001925 {
solenberg2100c0b2017-03-01 11:29:29 -08001926 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001927 EXPECT_EQ(103, gcodec.pltype);
1928 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001929 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001930 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001931 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001932 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001933 {
solenberg2100c0b2017-03-01 11:29:29 -08001934 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001935 EXPECT_EQ(103, gcodec.pltype);
1936 EXPECT_STREQ("ISAC", gcodec.plname);
1937 EXPECT_EQ(28000, gcodec.rate);
1938 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001939
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001942 {
solenberg2100c0b2017-03-01 11:29:29 -08001943 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001944 EXPECT_EQ(0, gcodec.pltype);
1945 EXPECT_STREQ("PCMU", gcodec.plname);
1946 EXPECT_EQ(64000, gcodec.rate);
1947 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001951 {
solenberg2100c0b2017-03-01 11:29:29 -08001952 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001953 EXPECT_EQ(0, gcodec.pltype);
1954 EXPECT_STREQ("PCMU", gcodec.plname);
1955 EXPECT_EQ(64000, gcodec.rate);
1956 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs[0] = kOpusCodec;
1959 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001961 {
solenberg2100c0b2017-03-01 11:29:29 -08001962 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001963 EXPECT_EQ(111, gcodec.pltype);
1964 EXPECT_STREQ("opus", gcodec.plname);
1965 EXPECT_EQ(32000, gcodec.rate);
1966 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967}
1968
Brave Yao5225dd82015-03-26 07:39:19 +08001969// Test that we could set packet size specified in kCodecParamPTime.
1970TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 cricket::AudioSendParameters parameters;
1973 parameters.codecs.push_back(kOpusCodec);
1974 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001975 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001977
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001978 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001979 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001980 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001981
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001984 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001985
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001986 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1987 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001988 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001989 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001990 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001991
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001992 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1993 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001994 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001995 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001996 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001997}
1998
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001999// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002000TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002001 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002002 cricket::AudioSendParameters parameters;
2003 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002004}
2005
2006// Test that we can set send codecs even with telephone-event codec as the first
2007// one on the list.
2008TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002009 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002011 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 parameters.codecs.push_back(kIsacCodec);
2013 parameters.codecs.push_back(kPcmuCodec);
2014 parameters.codecs[0].id = 98; // DTMF
2015 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002017 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002018 EXPECT_EQ(96, gcodec.pltype);
2019 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002020 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002021}
2022
solenberg31642aa2016-03-14 08:00:37 -07002023// Test that payload type range is limited for telephone-event codec.
2024TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002025 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002026 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002027 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002028 parameters.codecs.push_back(kIsacCodec);
2029 parameters.codecs[0].id = 0; // DTMF
2030 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002031 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002032 EXPECT_TRUE(channel_->CanInsertDtmf());
2033 parameters.codecs[0].id = 128; // DTMF
2034 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2035 EXPECT_FALSE(channel_->CanInsertDtmf());
2036 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002037 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002038 EXPECT_TRUE(channel_->CanInsertDtmf());
2039 parameters.codecs[0].id = -1; // DTMF
2040 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2041 EXPECT_FALSE(channel_->CanInsertDtmf());
2042}
2043
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002044// Test that we can set send codecs even with CN codec as the first
2045// one on the list.
2046TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002047 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002048 cricket::AudioSendParameters parameters;
2049 parameters.codecs.push_back(kCn16000Codec);
2050 parameters.codecs.push_back(kIsacCodec);
2051 parameters.codecs.push_back(kPcmuCodec);
2052 parameters.codecs[0].id = 98; // wideband CN
2053 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002055 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002056 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2057 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2058 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2059 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060}
2061
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002062// Test that we set VAD and DTMF types correctly as caller.
2063TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002065 cricket::AudioSendParameters parameters;
2066 parameters.codecs.push_back(kIsacCodec);
2067 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002068 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002069 parameters.codecs.push_back(kCn16000Codec);
2070 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002071 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002072 parameters.codecs[0].id = 96;
2073 parameters.codecs[2].id = 97; // wideband CN
2074 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002076 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002077 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2078 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2079 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2080 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2081 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2082 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002083 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002084}
2085
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002086// Test that we set VAD and DTMF types correctly as callee.
2087TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002088 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002089 cricket::AudioSendParameters parameters;
2090 parameters.codecs.push_back(kIsacCodec);
2091 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002092 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002093 parameters.codecs.push_back(kCn16000Codec);
2094 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002095 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002096 parameters.codecs[0].id = 96;
2097 parameters.codecs[2].id = 97; // wideband CN
2098 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002099 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002100 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002101 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002102
solenberg2100c0b2017-03-01 11:29:29 -08002103 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002104 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2105 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2106 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2107 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2108 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2109 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002110 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002111}
2112
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002113// Test that we only apply VAD if we have a CN codec that matches the
2114// send codec clockrate.
2115TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002116 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002117 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002119 parameters.codecs.push_back(kIsacCodec);
2120 parameters.codecs.push_back(kCn16000Codec);
2121 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002122 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002123 {
solenberg2100c0b2017-03-01 11:29:29 -08002124 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002125 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2126 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2127 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2128 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2129 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2130 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002131 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002132 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002133 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002134 {
solenberg2100c0b2017-03-01 11:29:29 -08002135 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002136 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2137 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2138 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002139 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002140 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002141 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002142 {
solenberg2100c0b2017-03-01 11:29:29 -08002143 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002144 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2145 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2146 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2147 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2148 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2149 }
Brave Yao5225dd82015-03-26 07:39:19 +08002150 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002151 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002152 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002153 {
solenberg2100c0b2017-03-01 11:29:29 -08002154 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002155 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2156 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2157 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158}
2159
2160// Test that we perform case-insensitive matching of codec names.
2161TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002162 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002163 cricket::AudioSendParameters parameters;
2164 parameters.codecs.push_back(kIsacCodec);
2165 parameters.codecs.push_back(kPcmuCodec);
2166 parameters.codecs.push_back(kCn16000Codec);
2167 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002168 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs[0].name = "iSaC";
2170 parameters.codecs[0].id = 96;
2171 parameters.codecs[2].id = 97; // wideband CN
2172 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002173 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002174 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002175 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2176 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2177 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2178 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2179 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2180 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002181 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002182}
2183
stefanba4c0e42016-02-04 04:12:24 -08002184class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2185 public:
2186 WebRtcVoiceEngineWithSendSideBweTest()
2187 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2188};
2189
2190TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2191 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002192 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002193 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002194 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2195 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2196 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002197 extension.id);
2198 return;
2199 }
2200 }
2201 FAIL() << "Transport sequence number extension not in header-extension list.";
2202}
2203
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002204// Test support for audio level header extension.
2205TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002206 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002207}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002208TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002209 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002210}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002211
solenbergd4adce42016-11-17 06:26:52 -08002212// Test support for transport sequence number header extension.
2213TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2214 TestSetSendRtpHeaderExtensions(
2215 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002216}
solenbergd4adce42016-11-17 06:26:52 -08002217TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2218 TestSetRecvRtpHeaderExtensions(
2219 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002220}
2221
solenberg1ac56142015-10-13 03:58:19 -07002222// Test that we can create a channel and start sending on it.
2223TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002224 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002225 SetSendParameters(send_parameters_);
2226 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002228 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002230}
2231
2232// Test that a channel will send if and only if it has a source and is enabled
2233// for sending.
2234TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002235 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002236 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002237 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002238 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002239 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2240 SetAudioSend(kSsrcX, true, &fake_source_);
2241 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2242 SetAudioSend(kSsrcX, true, nullptr);
2243 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002244}
2245
solenberg94218532016-06-16 10:53:22 -07002246// Test that a channel is muted/unmuted.
2247TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2248 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002249 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002250 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2251 SetAudioSend(kSsrcX, true, nullptr);
2252 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2253 SetAudioSend(kSsrcX, false, nullptr);
2254 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002255}
2256
solenberg6d6e7c52016-04-13 09:07:30 -07002257// Test that SetSendParameters() does not alter a stream's send state.
2258TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2259 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002260 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002261
2262 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002263 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002265
2266 // Changing RTP header extensions will recreate the AudioSendStream.
2267 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002268 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002269 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002270 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002271
2272 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002273 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002274 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002275
2276 // Changing RTP header extensions will recreate the AudioSendStream.
2277 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002278 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002279 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002280}
2281
solenberg1ac56142015-10-13 03:58:19 -07002282// Test that we can create a channel and start playing out on it.
2283TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002284 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002285 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002286 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002288 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290}
2291
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002292// Test that we can add and remove send streams.
2293TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2294 SetupForMultiSendStream();
2295
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002296 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002297 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002298
solenbergc96df772015-10-21 13:01:53 -07002299 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002300 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002301 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002302 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002303 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002304 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305 }
tfarina5237aaf2015-11-10 23:44:30 -08002306 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002307
solenbergc96df772015-10-21 13:01:53 -07002308 // Delete the send streams.
2309 for (uint32_t ssrc : kSsrcs4) {
2310 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002311 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002312 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002313 }
solenbergc96df772015-10-21 13:01:53 -07002314 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002315}
2316
2317// Test SetSendCodecs correctly configure the codecs in all send streams.
2318TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2319 SetupForMultiSendStream();
2320
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002321 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002322 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002324 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002325 }
2326
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002327 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002328 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002329 parameters.codecs.push_back(kIsacCodec);
2330 parameters.codecs.push_back(kCn16000Codec);
2331 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002332 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002333
2334 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002335 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002336 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2337 const auto& send_codec_spec =
2338 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2339 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2340 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2341 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2342 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2343 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002344 }
2345
minyue7a973442016-10-20 03:27:12 -07002346 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002347 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002348 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002349 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002350 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2351 const auto& send_codec_spec =
2352 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2353 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2354 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2355 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2356 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002357 }
2358}
2359
2360// Test we can SetSend on all send streams correctly.
2361TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2362 SetupForMultiSendStream();
2363
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002364 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002365 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002366 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002367 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002368 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002369 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002370 }
2371
2372 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002373 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002374 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002375 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002376 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002377 }
2378
2379 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002380 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002381 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002383 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002384 }
2385}
2386
2387// Test we can set the correct statistics on all send streams.
2388TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2389 SetupForMultiSendStream();
2390
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002392 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002393 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002394 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002395 }
solenberg85a04962015-10-27 03:35:21 -07002396
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002397 // Create a receive stream to check that none of the send streams end up in
2398 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002399 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002400
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002401 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002402 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002403 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002404 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002405
solenberg85a04962015-10-27 03:35:21 -07002406 // Check stats for the added streams.
2407 {
2408 cricket::VoiceMediaInfo info;
2409 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002410
solenberg85a04962015-10-27 03:35:21 -07002411 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002412 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002413 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002414 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002415 }
hbos1acfbd22016-11-17 23:43:29 -08002416 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002417
2418 // We have added one receive stream. We should see empty stats.
2419 EXPECT_EQ(info.receivers.size(), 1u);
2420 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002421 }
solenberg1ac56142015-10-13 03:58:19 -07002422
solenberg2100c0b2017-03-01 11:29:29 -08002423 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002424 {
2425 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002426 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002427 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002428 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002429 EXPECT_EQ(0u, info.receivers.size());
2430 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002431
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002432 // Deliver a new packet - a default receive stream should be created and we
2433 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002434 {
2435 cricket::VoiceMediaInfo info;
2436 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2437 SetAudioReceiveStreamStats();
2438 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002439 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002440 EXPECT_EQ(1u, info.receivers.size());
2441 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002442 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002443 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002444}
2445
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002446// Test that we can add and remove receive streams, and do proper send/playout.
2447// We can receive on multiple streams while sending one stream.
2448TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002449 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450
solenberg1ac56142015-10-13 03:58:19 -07002451 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002452 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002453 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454
solenberg1ac56142015-10-13 03:58:19 -07002455 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002456 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002457 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002458 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459
solenberg1ac56142015-10-13 03:58:19 -07002460 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002461 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462
2463 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2465 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2466 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467
2468 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002469 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002470 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471
2472 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002473 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002474 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2475 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476
aleloi84ef6152016-08-04 05:28:21 -07002477 // Restart playout and make sure recv streams are played out.
2478 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2480 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481
aleloi84ef6152016-08-04 05:28:21 -07002482 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2484 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485}
2486
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002488// and start sending on it.
2489TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002490 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002491 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2492 EXPECT_CALL(apm_gc_,
2493 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002494 SetSendParameters(send_parameters_);
2495 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002496 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002497 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002498 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499}
2500
wu@webrtc.org97077a32013-10-25 21:18:33 +00002501TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002502 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002503 EXPECT_CALL(adm_,
2504 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002505 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2506 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002507 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2508 send_parameters_.options.tx_agc_digital_compression_gain =
2509 rtc::Optional<uint16_t>(9);
2510 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2511 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002512 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2513 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2514 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002515 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002516
2517 // Check interaction with adjust_agc_delta. Both should be respected, for
2518 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002519 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002520 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002521 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002522}
2523
wu@webrtc.org97077a32013-10-25 21:18:33 +00002524TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002525 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002526 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2527 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002528 send_parameters_.options.recording_sample_rate =
2529 rtc::Optional<uint32_t>(48000);
2530 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002531 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002532}
2533
minyue6b825df2016-10-31 04:08:32 -07002534TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2535 EXPECT_TRUE(SetupSendStream());
2536 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2537 send_parameters_.options.audio_network_adaptor_config =
2538 rtc::Optional<std::string>("1234");
2539 SetSendParameters(send_parameters_);
2540 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002541 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002542}
2543
2544TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2545 EXPECT_TRUE(SetupSendStream());
2546 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2547 send_parameters_.options.audio_network_adaptor_config =
2548 rtc::Optional<std::string>("1234");
2549 SetSendParameters(send_parameters_);
2550 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002551 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002552 const int initial_num = call_.GetNumCreatedSendStreams();
2553 cricket::AudioOptions options;
2554 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002555 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002556 // AudioSendStream expected to be recreated.
2557 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002558 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002559}
2560
2561TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2562 EXPECT_TRUE(SetupSendStream());
2563 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2564 send_parameters_.options.audio_network_adaptor_config =
2565 rtc::Optional<std::string>("1234");
2566 SetSendParameters(send_parameters_);
2567 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002568 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002569 const int initial_num = call_.GetNumCreatedSendStreams();
2570 cricket::AudioOptions options;
2571 options.audio_network_adaptor = rtc::Optional<bool>();
2572 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2573 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002574 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002575 // AudioSendStream not expected to be recreated.
2576 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2577 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002578 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002579}
2580
michaelt6672b262017-01-11 10:17:59 -08002581class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2582 : public WebRtcVoiceEngineTestFake {
2583 public:
2584 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2585 : WebRtcVoiceEngineTestFake(
2586 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2587 "Enabled/") {}
2588};
2589
2590TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2591 EXPECT_TRUE(SetupSendStream());
2592 cricket::AudioSendParameters parameters;
2593 parameters.codecs.push_back(kOpusCodec);
2594 SetSendParameters(parameters);
2595 const int initial_num = call_.GetNumCreatedSendStreams();
2596 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2597
2598 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2599 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002600 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2601 constexpr int kMinOverheadBps =
2602 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002603 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2604
2605 constexpr int kOpusMinBitrateBps = 6000;
2606 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002607 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002608 constexpr int kOpusBitrateFbBps = 32000;
2609 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002610 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002611
2612 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2613 parameters.options.audio_network_adaptor_config =
2614 rtc::Optional<std::string>("1234");
2615 SetSendParameters(parameters);
2616
ossu11bfc532017-02-16 05:37:06 -08002617 constexpr int kMinOverheadWithAnaBps =
2618 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002619 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2620
2621 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002622 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002623
2624 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002625 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002626}
2627
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002628// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002629// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002630TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002631 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002632 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002633}
2634
2635TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2636 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002637 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002638 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002639 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002640 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002641 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002642 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002643 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002644
solenberg85a04962015-10-27 03:35:21 -07002645 // Check stats for the added streams.
2646 {
2647 cricket::VoiceMediaInfo info;
2648 EXPECT_EQ(true, channel_->GetStats(&info));
2649
2650 // We have added one send stream. We should see the stats we've set.
2651 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002652 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002653 // We have added one receive stream. We should see empty stats.
2654 EXPECT_EQ(info.receivers.size(), 1u);
2655 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2656 }
solenberg1ac56142015-10-13 03:58:19 -07002657
solenberg566ef242015-11-06 15:34:49 -08002658 // Start sending - this affects some reported stats.
2659 {
2660 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002661 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002662 EXPECT_EQ(true, channel_->GetStats(&info));
2663 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002664 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002665 }
2666
solenberg2100c0b2017-03-01 11:29:29 -08002667 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002668 {
2669 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002670 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002671 EXPECT_EQ(true, channel_->GetStats(&info));
2672 EXPECT_EQ(1u, info.senders.size());
2673 EXPECT_EQ(0u, info.receivers.size());
2674 }
solenberg1ac56142015-10-13 03:58:19 -07002675
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002676 // Deliver a new packet - a default receive stream should be created and we
2677 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002678 {
2679 cricket::VoiceMediaInfo info;
2680 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2681 SetAudioReceiveStreamStats();
2682 EXPECT_EQ(true, channel_->GetStats(&info));
2683 EXPECT_EQ(1u, info.senders.size());
2684 EXPECT_EQ(1u, info.receivers.size());
2685 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002686 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002687 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688}
2689
2690// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002691// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002692TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002693 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002694 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2695 EXPECT_TRUE(AddRecvStream(kSsrcY));
2696 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002697}
2698
2699// Test that the local SSRC is the same on sending and receiving channels if the
2700// receive channel is created before the send channel.
2701TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002703 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002705 cricket::StreamParams::CreateLegacy(kSsrcX)));
2706 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2707 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002708}
2709
2710// Test that we can properly receive packets.
2711TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002712 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002713 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002715
2716 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2717 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718}
2719
2720// Test that we can properly receive packets on multiple streams.
2721TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002722 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002723 const uint32_t ssrc1 = 1;
2724 const uint32_t ssrc2 = 2;
2725 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002726 EXPECT_TRUE(AddRecvStream(ssrc1));
2727 EXPECT_TRUE(AddRecvStream(ssrc2));
2728 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002730 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002731 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002733 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734 }
mflodman3d7db262016-04-29 00:57:13 -07002735
2736 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2737 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2738 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2739
2740 EXPECT_EQ(s1.received_packets(), 0);
2741 EXPECT_EQ(s2.received_packets(), 0);
2742 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002743
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002745 EXPECT_EQ(s1.received_packets(), 0);
2746 EXPECT_EQ(s2.received_packets(), 0);
2747 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002748
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002750 EXPECT_EQ(s1.received_packets(), 1);
2751 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2752 EXPECT_EQ(s2.received_packets(), 0);
2753 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002754
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002756 EXPECT_EQ(s1.received_packets(), 1);
2757 EXPECT_EQ(s2.received_packets(), 1);
2758 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2759 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002760
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002762 EXPECT_EQ(s1.received_packets(), 1);
2763 EXPECT_EQ(s2.received_packets(), 1);
2764 EXPECT_EQ(s3.received_packets(), 1);
2765 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002766
mflodman3d7db262016-04-29 00:57:13 -07002767 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2768 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2769 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770}
2771
solenberg2100c0b2017-03-01 11:29:29 -08002772// Test that receiving on an unsignaled stream works (a stream is created).
2773TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002774 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002775 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2776
solenberg7e63ef02015-11-20 00:19:43 -08002777 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002778
2779 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002780 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2781 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002782}
2783
solenberg2100c0b2017-03-01 11:29:29 -08002784// Test that receiving N unsignaled stream works (streams will be created), and
2785// that packets are forwarded to them all.
2786TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002787 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002788 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002789 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2790
solenberg2100c0b2017-03-01 11:29:29 -08002791 constexpr uint32_t kMaxUnsignaledCount = 50;
2792
2793 // Note that SSRC = 0 is not supported.
2794 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002795 rtc::SetBE32(&packet[8], ssrc);
2796 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002797
solenberg2100c0b2017-03-01 11:29:29 -08002798 // Verify we have one new stream for each loop iteration.
2799 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002800 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2801 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002802 }
mflodman3d7db262016-04-29 00:57:13 -07002803
solenberg2100c0b2017-03-01 11:29:29 -08002804 // Sending on the same SSRCs again should not create new streams.
2805 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledCount); ++ssrc) {
2806 rtc::SetBE32(&packet[8], ssrc);
2807 DeliverPacket(packet, sizeof(packet));
2808
2809 EXPECT_EQ(kMaxUnsignaledCount, call_.GetAudioReceiveStreams().size());
2810 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2811 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2812 }
2813
2814 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2815 constexpr uint32_t kAnotherSsrc = 667;
2816 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002817 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002818
2819 const auto& streams = call_.GetAudioReceiveStreams();
2820 EXPECT_EQ(kMaxUnsignaledCount, streams.size());
2821 size_t i = 0;
2822 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledCount); ++ssrc, ++i) {
2823 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2824 EXPECT_EQ(2, streams[i]->received_packets());
2825 }
2826 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2827 EXPECT_EQ(1, streams[i]->received_packets());
2828 // Sanity check that we've checked all streams.
2829 EXPECT_EQ(kMaxUnsignaledCount, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002830}
2831
solenberg2100c0b2017-03-01 11:29:29 -08002832// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002833// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002834TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002835 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002836 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002837 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2838
2839 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002840 const uint32_t signaled_ssrc = 1;
2841 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002842 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002843 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002844 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2845 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002846 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002847
2848 // Note that the first unknown SSRC cannot be 0, because we only support
2849 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002850 const uint32_t unsignaled_ssrc = 7011;
2851 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002852 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002853 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2854 packet, sizeof(packet)));
2855 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2856
2857 DeliverPacket(packet, sizeof(packet));
2858 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2859
2860 rtc::SetBE32(&packet[8], signaled_ssrc);
2861 DeliverPacket(packet, sizeof(packet));
2862 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2863 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002864}
2865
solenberg4904fb62017-02-17 12:01:14 -08002866// Two tests to verify that adding a receive stream with the same SSRC as a
2867// previously added unsignaled stream will only recreate underlying stream
2868// objects if the stream parameters have changed.
2869TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2870 EXPECT_TRUE(SetupChannel());
2871
2872 // Spawn unsignaled stream with SSRC=1.
2873 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2874 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2875 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2876 sizeof(kPcmuFrame)));
2877
2878 // Verify that the underlying stream object in Call is not recreated when a
2879 // stream with SSRC=1 is added.
2880 const auto& streams = call_.GetAudioReceiveStreams();
2881 EXPECT_EQ(1, streams.size());
2882 int audio_receive_stream_id = streams.front()->id();
2883 EXPECT_TRUE(AddRecvStream(1));
2884 EXPECT_EQ(1, streams.size());
2885 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2886}
2887
2888TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2889 EXPECT_TRUE(SetupChannel());
2890
2891 // Spawn unsignaled stream with SSRC=1.
2892 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2893 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2894 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2895 sizeof(kPcmuFrame)));
2896
2897 // Verify that the underlying stream object in Call *is* recreated when a
2898 // stream with SSRC=1 is added, and which has changed stream parameters.
2899 const auto& streams = call_.GetAudioReceiveStreams();
2900 EXPECT_EQ(1, streams.size());
2901 int audio_receive_stream_id = streams.front()->id();
2902 cricket::StreamParams stream_params;
2903 stream_params.ssrcs.push_back(1);
2904 stream_params.sync_label = "sync_label";
2905 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2906 EXPECT_EQ(1, streams.size());
2907 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2908}
2909
solenberg0a617e22015-10-20 15:49:38 -07002910// Test that we properly handle failures to add a receive stream.
2911TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002912 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002914 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915}
2916
solenberg0a617e22015-10-20 15:49:38 -07002917// Test that we properly handle failures to add a send stream.
2918TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002919 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002920 voe_.set_fail_create_channel(true);
2921 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2922}
2923
solenberg1ac56142015-10-13 03:58:19 -07002924// Test that AddRecvStream creates new stream.
2925TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002926 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002928 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002929 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930}
2931
2932// Test that after adding a recv stream, we do not decode more codecs than
2933// those previously passed into SetRecvCodecs.
2934TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002935 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 cricket::AudioRecvParameters parameters;
2937 parameters.codecs.push_back(kIsacCodec);
2938 parameters.codecs.push_back(kPcmuCodec);
2939 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002940 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002941 int channel_num2 = voe_.GetLastChannel();
2942 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002943 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002944 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945 gcodec.channels = 2;
2946 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2947}
2948
2949// Test that we properly clean up any streams that were added, even if
2950// not explicitly removed.
2951TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002952 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002953 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002954 EXPECT_TRUE(AddRecvStream(1));
2955 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2957 delete channel_;
2958 channel_ = NULL;
2959 EXPECT_EQ(0, voe_.GetNumChannels());
2960}
2961
wu@webrtc.org78187522013-10-07 23:32:02 +00002962TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002963 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002964 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002965}
2966
2967TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002968 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002969 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002970 // Manually delete channel to simulate a failure.
2971 int channel = voe_.GetLastChannel();
2972 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2973 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002974 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002975 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002976 EXPECT_NE(channel, new_channel);
2977 // The last created channel is deleted too.
2978 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002979}
2980
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002981// Test the InsertDtmf on default send stream as caller.
2982TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002983 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984}
2985
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002986// Test the InsertDtmf on default send stream as callee
2987TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002988 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002989}
2990
2991// Test the InsertDtmf on specified send stream as caller.
2992TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002993 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002994}
2995
2996// Test the InsertDtmf on specified send stream as callee.
2997TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002998 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999}
3000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003002 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003003 EXPECT_CALL(adm_,
3004 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3005 EXPECT_CALL(adm_,
3006 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3007 EXPECT_CALL(adm_,
3008 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003009
solenberg246b8172015-12-08 09:50:23 -08003010 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3011 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012
solenberg246b8172015-12-08 09:50:23 -08003013 // Nothing set in AudioOptions, so everything should be as default.
3014 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003015 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003016 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003017 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3018 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019
3020 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003021 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3022 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003023 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003024 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025
3026 // Turn echo cancellation back on, with settings, and make sure
3027 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003028 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3029 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003030 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003031 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003033 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3034 // control.
solenberg76377c52017-02-21 00:54:31 -08003035 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3036 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003037 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003038 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003039
3040 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003041 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3042 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003043 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3044 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3045 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003046 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003047
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003048 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003049 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3050 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003051 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003052 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003053
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003054 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003055 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3056 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3057 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3058 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003059 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003060 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003061
3062 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003063 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3064 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3065 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3066 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003067 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3068 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003069 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003070
3071 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003072 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3073 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3074 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3075 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3076 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3077 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3078 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003079 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3080 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3081 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3082 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003083 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003084 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003085
solenberg1ac56142015-10-13 03:58:19 -07003086 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003087 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3088 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3089 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3090 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3091 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3092 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3093 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003094 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003095}
3096
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003097TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003098 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003099 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003100 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003101 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003102 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003103 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003104 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003105 EXPECT_CALL(adm_,
3106 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3107 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3108 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3109 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3110 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003111
kwiberg686a8ef2016-02-26 03:00:35 -08003112 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003113 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003114 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003115 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003116 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003117 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003118
3119 // Have to add a stream to make SetSend work.
3120 cricket::StreamParams stream1;
3121 stream1.ssrcs.push_back(1);
3122 channel1->AddSendStream(stream1);
3123 cricket::StreamParams stream2;
3124 stream2.ssrcs.push_back(2);
3125 channel2->AddSendStream(stream2);
3126
3127 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003128 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003129 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3130 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3131 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003132 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3133 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3134 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3135 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3136 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003137 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003138 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003139 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003140 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003141
3142 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003143 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003144 parameters_options_no_ns.options.noise_suppression =
3145 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003146 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3147 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3148 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3149 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3150 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003151 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003152 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003153 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3154 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3155 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003156 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003157
3158 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003159 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003160 parameters_options_no_agc.options.auto_gain_control =
3161 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003162 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3163 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3164 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3165 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3166 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003167 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003168 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3169 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3170 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003171 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003172
solenberg76377c52017-02-21 00:54:31 -08003173 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3174 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3175 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3176 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3177 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003178 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003179
solenberg76377c52017-02-21 00:54:31 -08003180 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3181 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3182 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3183 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3184 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003185 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003186
solenberg76377c52017-02-21 00:54:31 -08003187 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3188 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3189 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3190 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3191 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003192 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003193
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003194 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003195 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3196 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003197 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003198 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003199 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003200 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003201 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3202 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3203 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3204 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3205 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003206 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003207 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3208 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3209 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003210 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003211}
3212
wu@webrtc.orgde305012013-10-31 15:40:38 +00003213// This test verifies DSCP settings are properly applied on voice media channel.
3214TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003215 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003216 cricket::FakeNetworkInterface network_interface;
3217 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003218 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003219
solenberg059fb442016-10-26 05:12:24 -07003220 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3221 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3222
solenbergbc37fc82016-04-04 09:54:44 -07003223 channel.reset(
3224 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003225 channel->SetInterface(&network_interface);
3226 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3227 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3228
3229 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003230 channel.reset(
3231 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003232 channel->SetInterface(&network_interface);
3233 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3234
3235 // Verify that setting the option to false resets the
3236 // DiffServCodePoint.
3237 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003238 channel.reset(
3239 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003240 channel->SetInterface(&network_interface);
3241 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3242 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3243
3244 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003245}
3246
solenberg1ac56142015-10-13 03:58:19 -07003247TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003248 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003249 cricket::WebRtcVoiceMediaChannel* media_channel =
3250 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003251 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003253 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003254 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3255 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3256 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003257 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003258 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003259}
3260
solenberg1ac56142015-10-13 03:58:19 -07003261TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003262 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003263 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003264 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3265 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3266 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003267 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003268 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003269 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3270 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003271 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003272 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003273 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003274 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003275}
3276
solenberg4bac9c52015-10-09 02:32:53 -07003277TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003278 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003280 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003281 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003282 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003283 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3284 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3285 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003286}
3287
solenberg2100c0b2017-03-01 11:29:29 -08003288TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003289 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003290
3291 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003292 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003293 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3294
3295 // Should remember the volume "2" which will be set on new unsignaled streams,
3296 // and also set the gain to 2 on existing unsignaled streams.
3297 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3298 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3299
3300 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3301 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3302 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3303 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3304 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3305 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3306
3307 // Setting gain with SSRC=0 should affect all unsignaled streams.
3308 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
3309 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3310 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3311
3312 // Setting gain on an individual stream affects only that.
3313 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
3314 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3315 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003316}
3317
pbos8fc7fa72015-07-15 08:02:58 -07003318TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003319 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003320 const std::string kSyncLabel = "AvSyncLabel";
3321
solenbergff976312016-03-30 23:28:51 -07003322 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003323 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3324 sp.sync_label = kSyncLabel;
3325 // Creating two channels to make sure that sync label is set properly for both
3326 // the default voice channel and following ones.
3327 EXPECT_TRUE(channel_->AddRecvStream(sp));
3328 sp.ssrcs[0] += 1;
3329 EXPECT_TRUE(channel_->AddRecvStream(sp));
3330
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003331 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003332 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003333 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003334 << "SyncGroup should be set based on sync_label";
3335 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003336 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003337 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003338}
3339
solenberg3a941542015-11-16 07:34:50 -08003340// TODO(solenberg): Remove, once recv streams are configured through Call.
3341// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003342TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343 // Test that setting the header extensions results in the expected state
3344 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003345 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003346 ssrcs.push_back(223);
3347 ssrcs.push_back(224);
3348
solenbergff976312016-03-30 23:28:51 -07003349 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003350 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003351 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003352 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003353 cricket::StreamParams::CreateLegacy(ssrc)));
3354 }
3355
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003356 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003357 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003358 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003359 EXPECT_NE(nullptr, s);
3360 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3361 }
3362
3363 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003364 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003365 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003366 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003367 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003368 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003369 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003370 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 EXPECT_NE(nullptr, s);
3372 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003373 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3374 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003375 for (const auto& s_ext : s_exts) {
3376 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003377 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003378 }
3379 }
3380 }
3381 }
3382
3383 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003384 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003385 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003386 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003387 EXPECT_NE(nullptr, s);
3388 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3389 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003390}
3391
3392TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3393 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003394 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003395 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003396 static const unsigned char kRtcp[] = {
3397 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3398 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3401 };
jbaucheec21bd2016-03-20 06:15:43 -07003402 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003403
solenbergff976312016-03-30 23:28:51 -07003404 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003405 cricket::WebRtcVoiceMediaChannel* media_channel =
3406 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003407 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003408 EXPECT_TRUE(media_channel->AddRecvStream(
3409 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3410
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003411 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003412 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003413 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003414 EXPECT_EQ(0, s->received_packets());
3415 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3416 EXPECT_EQ(1, s->received_packets());
3417 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3418 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003419}
Minyue2013aec2015-05-13 14:14:42 +02003420
solenberg0a617e22015-10-20 15:49:38 -07003421// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003422// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003423TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003424 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003425 EXPECT_TRUE(AddRecvStream(kSsrcY));
3426 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003427 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003428 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3429 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3430 EXPECT_TRUE(AddRecvStream(kSsrcW));
3431 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003432}
3433
solenberg7602aab2016-11-14 11:30:07 -08003434TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3435 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003436 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003437 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003438 cricket::StreamParams::CreateLegacy(kSsrcY)));
3439 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3440 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3441 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003442 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003443 cricket::StreamParams::CreateLegacy(kSsrcW)));
3444 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3445 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003446}
stefan658910c2015-09-03 05:48:32 -07003447
deadbeef884f5852016-01-15 09:20:04 -08003448TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003449 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003450 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3451 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003452
3453 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003454 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3455 EXPECT_TRUE(AddRecvStream(kSsrcX));
3456 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003457
3458 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003459 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3460 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003461
3462 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003463 channel_->SetRawAudioSink(kSsrcX, nullptr);
3464 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003465}
3466
solenberg2100c0b2017-03-01 11:29:29 -08003467TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003468 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003469 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3470 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003471 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3472 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003473
3474 // Should be able to set a default sink even when no stream exists.
3475 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3476
solenberg2100c0b2017-03-01 11:29:29 -08003477 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3478 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003479 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003480 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003481
3482 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003483 channel_->SetRawAudioSink(kSsrc0, nullptr);
3484 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003485
3486 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003487 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3488 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003489
3490 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003491 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003492 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003493 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3494
3495 // Spawn another unsignaled stream - it should be assigned the default sink
3496 // and the previous unsignaled stream should lose it.
3497 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3498 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3499 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3500 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3501 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3502 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3503
3504 // Reset the default sink - the second unsignaled stream should lose it.
3505 channel_->SetRawAudioSink(kSsrc0, nullptr);
3506 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3507 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3508
3509 // Try setting the default sink while two streams exists.
3510 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
3511 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3512 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3513
3514 // Try setting the sink for the first unsignaled stream using its known SSRC.
3515 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
3516 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3517 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3518 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003519}
3520
skvlad7a43d252016-03-22 15:32:27 -07003521// Test that, just like the video channel, the voice channel communicates the
3522// network state to the call.
3523TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003524 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003525
3526 EXPECT_EQ(webrtc::kNetworkUp,
3527 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3528 EXPECT_EQ(webrtc::kNetworkUp,
3529 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3530
3531 channel_->OnReadyToSend(false);
3532 EXPECT_EQ(webrtc::kNetworkDown,
3533 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3534 EXPECT_EQ(webrtc::kNetworkUp,
3535 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3536
3537 channel_->OnReadyToSend(true);
3538 EXPECT_EQ(webrtc::kNetworkUp,
3539 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3540 EXPECT_EQ(webrtc::kNetworkUp,
3541 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3542}
3543
aleloi18e0b672016-10-04 02:45:47 -07003544// Test that playout is still started after changing parameters
3545TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3546 SetupRecvStream();
3547 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003548 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003549
3550 // Changing RTP header extensions will recreate the AudioReceiveStream.
3551 cricket::AudioRecvParameters parameters;
3552 parameters.extensions.push_back(
3553 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3554 channel_->SetRecvParameters(parameters);
3555
solenberg2100c0b2017-03-01 11:29:29 -08003556 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003557}
3558
stefan658910c2015-09-03 05:48:32 -07003559// Tests that the library initializes and shuts down properly.
3560TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003561 // If the VoiceEngine wants to gather available codecs early, that's fine but
3562 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003563 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003564 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003565 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003566 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003567 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003568 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3569 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003570 EXPECT_TRUE(channel != nullptr);
3571 delete channel;
solenbergff976312016-03-30 23:28:51 -07003572}
stefan658910c2015-09-03 05:48:32 -07003573
solenbergff976312016-03-30 23:28:51 -07003574// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003575TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3576 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3577 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3578 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003579 // Return 100ms just in case this function gets called. If we don't,
3580 // we could enter a tight loop since the mock would return 0.
3581 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003582 {
ossuc54071d2016-08-17 02:45:41 -07003583 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003584 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003585 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003586 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003587 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003588 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3589 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3590 EXPECT_TRUE(channel != nullptr);
3591 delete channel;
3592 }
stefan658910c2015-09-03 05:48:32 -07003593}
3594
3595// Tests that the library is configured with the codecs we want.
3596TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003597 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3598 // module.
3599
stefan658910c2015-09-03 05:48:32 -07003600 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003601#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003602 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003603 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003604#endif
3605#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003606 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003607 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003608#endif
3609#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003610 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003611 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003612#endif
3613#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003614 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003615 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003616 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003617 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003618 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003619#endif
solenberg26c8c912015-11-27 04:00:25 -08003620 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003621 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003622 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003623 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003624 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003625 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003626 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3627 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3628 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3629 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3630 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3631 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003632 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003633 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003634 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003635 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003636 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003637 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003638 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003639 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003640 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003641 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003642 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003643 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003644 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003649 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003650 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003651 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003652 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003653 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003654 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003655
stefan658910c2015-09-03 05:48:32 -07003656 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003657 // TODO(ossu): Why are the payload types of codecs with non-static payload
3658 // type assignments checked here? It shouldn't really matter.
3659 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003660 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003661 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3662 if (codec.name == "CN" && codec.clockrate == 16000) {
3663 EXPECT_EQ(105, codec.id);
3664 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3665 EXPECT_EQ(106, codec.id);
3666 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3667 EXPECT_EQ(103, codec.id);
3668 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3669 EXPECT_EQ(104, codec.id);
3670 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3671 EXPECT_EQ(9, codec.id);
3672 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3673 EXPECT_EQ(126, codec.id);
3674 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3675 // Remove these checks once both send and receive side assigns payload types
3676 // dynamically.
3677 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3678 EXPECT_EQ(113, codec.id);
3679 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3680 EXPECT_EQ(112, codec.id);
3681 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3682 EXPECT_EQ(110, codec.id);
3683 } else if (codec.name == "opus") {
3684 EXPECT_EQ(111, codec.id);
3685 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3686 EXPECT_EQ("10", codec.params.find("minptime")->second);
3687 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3688 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003689 }
3690 }
stefan658910c2015-09-03 05:48:32 -07003691}
3692
3693// Tests that VoE supports at least 32 channels
3694TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003695 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003696 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003697 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003698 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003699 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003700
3701 cricket::VoiceMediaChannel* channels[32];
3702 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003703 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003704 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3705 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003706 if (!channel)
3707 break;
stefan658910c2015-09-03 05:48:32 -07003708 channels[num_channels++] = channel;
3709 }
3710
tfarina5237aaf2015-11-10 23:44:30 -08003711 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003712 EXPECT_EQ(expected, num_channels);
3713
3714 while (num_channels > 0) {
3715 delete channels[--num_channels];
3716 }
stefan658910c2015-09-03 05:48:32 -07003717}
3718
3719// Test that we set our preferred codecs properly.
3720TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003721 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3722 // - Check that our builtin codecs are usable by Channel.
3723 // - The codecs provided by the engine is usable by Channel.
3724 // It does not check that the codecs in the RecvParameters are actually
3725 // what we sent in - though it's probably reasonable to expect so, if
3726 // SetRecvParameters returns true.
3727 // I think it will become clear once audio decoder injection is completed.
3728 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003729 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003730 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003731 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003732 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003733 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3734 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003735 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003736 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003737 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003738}
ossu9def8002017-02-09 05:14:32 -08003739
3740TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3741 std::vector<webrtc::AudioCodecSpec> specs;
3742 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3743 spec1.allow_comfort_noise = false;
3744 spec1.supports_network_adaption = true;
3745 specs.push_back(spec1);
3746 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3747 spec2.allow_comfort_noise = false;
3748 specs.push_back(spec2);
3749 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3750 {{"param1", "value1b"},
3751 {"param2", "value2"}}}));
3752 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3753 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3754
3755 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3756 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3757 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3758 .WillOnce(Return(specs));
3759
3760 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3761 auto codecs = engine.recv_codecs();
3762 EXPECT_EQ(11, codecs.size());
3763
3764 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3765 // check the actual values safely, to provide better test results.
3766 auto get_codec =
3767 [&codecs](size_t index) -> const cricket::AudioCodec& {
3768 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3769 if (codecs.size() > index)
3770 return codecs[index];
3771 return missing_codec;
3772 };
3773
3774 // Ensure the general codecs are generated first and in order.
3775 for (size_t i = 0; i != specs.size(); ++i) {
3776 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3777 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3778 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3779 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3780 }
3781
3782 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003783 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003784 auto find_codec =
3785 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3786 for (size_t i = 0; i != codecs.size(); ++i) {
3787 const cricket::AudioCodec& codec = codecs[i];
3788 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3789 codec.clockrate == format.clockrate_hz &&
3790 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003791 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003792 }
3793 }
3794 return -1;
3795 };
3796
3797 // Ensure all supplementary codecs are generated last. Their internal ordering
3798 // is not important.
3799 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3800 const int num_specs = static_cast<int>(specs.size());
3801 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3802 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3803 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3804 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3805 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3806 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3807 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3808}