blob: b57f4ee568b4dcf4bd441f7abb208fe5c49ef4f1 [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
kwiberg1c07c702017-03-27 07:15:49 -070034using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070035using testing::Return;
36using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000037
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020038namespace {
39
solenbergebb349d2017-03-13 05:46:15 -070040constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
41
deadbeef67cf2c12016-04-13 10:07:16 -070042const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
43const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
44const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
45const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
46const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070047const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
48const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080049const cricket::AudioCodec
50 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
51const cricket::AudioCodec
52 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
53
solenberg2100c0b2017-03-01 11:29:29 -080054const uint32_t kSsrc0 = 0;
55const uint32_t kSsrc1 = 1;
56const uint32_t kSsrcX = 0x99;
57const uint32_t kSsrcY = 0x17;
58const uint32_t kSsrcZ = 0x42;
59const uint32_t kSsrcW = 0x02;
60const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
solenberg971cab02016-06-14 10:02:41 -070062constexpr int kRtpHistoryMs = 5000;
63
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064class FakeVoEWrapper : public cricket::VoEWrapper {
65 public:
66 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg76377c52017-02-21 00:54:31 -080067 : cricket::VoEWrapper(engine, // base
solenberg9a5f032222017-03-15 06:14:12 -070068 engine) { // codec
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 }
70};
skvlad11a9cbf2016-10-07 11:53:05 -070071
solenberg76377c52017-02-21 00:54:31 -080072class MockTransmitMixer : public webrtc::voe::TransmitMixer {
73 public:
74 MockTransmitMixer() = default;
75 virtual ~MockTransmitMixer() = default;
76
77 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
78};
solenberg9a5f032222017-03-15 06:14:12 -070079
80void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
81 RTC_DCHECK(adm);
82 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
83 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
84#if !defined(WEBRTC_IOS)
85 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
86 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
87 ChannelType::kChannelBoth)).WillOnce(Return(0));
88#if defined(WEBRTC_WIN)
89 EXPECT_CALL(*adm, SetRecordingDevice(
90 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
91 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
92 .WillOnce(Return(0));
93#else
94 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
95#endif // #if defined(WEBRTC_WIN)
96 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
97 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
98 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
99 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
100#if defined(WEBRTC_WIN)
101 EXPECT_CALL(*adm, SetPlayoutDevice(
102 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
103 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
104 .WillOnce(Return(0));
105#else
106 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
107#endif // #if defined(WEBRTC_WIN)
108 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
109 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
110 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
111#endif // #if !defined(WEBRTC_IOS)
112 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
116}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200117} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118
solenbergff976312016-03-30 23:28:51 -0700119// Tests that our stub library "works".
120TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700121 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700122 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700123 StrictMock<webrtc::test::MockAudioProcessing> apm;
124 EXPECT_CALL(apm, ApplyConfig(testing::_));
125 EXPECT_CALL(apm, SetExtraOptions(testing::_));
126 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800127 StrictMock<MockTransmitMixer> transmit_mixer;
128 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
129 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700130 EXPECT_FALSE(voe.IsInited());
131 {
ossuc54071d2016-08-17 02:45:41 -0700132 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -0800133 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700134 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700135 EXPECT_TRUE(voe.IsInited());
136 }
137 EXPECT_FALSE(voe.IsInited());
138}
139
deadbeef884f5852016-01-15 09:20:04 -0800140class FakeAudioSink : public webrtc::AudioSinkInterface {
141 public:
142 void OnData(const Data& audio) override {}
143};
144
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800145class FakeAudioSource : public cricket::AudioSource {
146 void SetSink(Sink* sink) override {}
147};
148
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149class WebRtcVoiceEngineTestFake : public testing::Test {
150 public:
stefanba4c0e42016-02-04 04:12:24 -0800151 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
152
153 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800154 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
155 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
156 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700157 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800158 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700159 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800160 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700161 EXPECT_CALL(apm_, ApplyConfig(testing::_));
162 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
163 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800164 // Default Options.
165 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
166 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
167 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
168 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
169 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
170 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
171 // Init does not overwrite default AGC config.
172 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
173 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
174 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
175 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
176 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
177 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800178 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
179 // the tests here probe the specific set of codecs provided by the builtin
180 // factory. Those tests should probably be moved elsewhere.
181 engine_.reset(new cricket::WebRtcVoiceEngine(
182 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
183 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200184 send_parameters_.codecs.push_back(kPcmuCodec);
185 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800186 // Default Options.
187 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000188 }
solenberg8189b022016-06-14 12:13:00 -0700189
solenbergff976312016-03-30 23:28:51 -0700190 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700191 EXPECT_CALL(apm_, ApplyConfig(testing::_));
192 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700193 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
194 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200195 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000196 }
solenberg8189b022016-06-14 12:13:00 -0700197
solenbergff976312016-03-30 23:28:51 -0700198 bool SetupRecvStream() {
199 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700200 return false;
201 }
solenberg2100c0b2017-03-01 11:29:29 -0800202 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700203 }
solenberg8189b022016-06-14 12:13:00 -0700204
solenbergff976312016-03-30 23:28:51 -0700205 bool SetupSendStream() {
206 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000207 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 }
solenberg2100c0b2017-03-01 11:29:29 -0800209 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800210 return false;
211 }
solenberg059fb442016-10-26 05:12:24 -0700212 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800213 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
solenberg8189b022016-06-14 12:13:00 -0700215
216 bool AddRecvStream(uint32_t ssrc) {
217 EXPECT_TRUE(channel_);
218 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
219 }
220
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000221 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700222 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700223 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800224 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
225 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700226 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800227 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000228 }
solenberg8189b022016-06-14 12:13:00 -0700229
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700231 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000232 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
solenberg8189b022016-06-14 12:13:00 -0700234
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200235 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 }
238
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100239 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
240 const auto* send_stream = call_.GetAudioSendStream(ssrc);
241 EXPECT_TRUE(send_stream);
242 return *send_stream;
243 }
244
deadbeef884f5852016-01-15 09:20:04 -0800245 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
246 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
247 EXPECT_TRUE(recv_stream);
248 return *recv_stream;
249 }
250
solenberg3a941542015-11-16 07:34:50 -0800251 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800252 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800253 }
254
solenberg7add0582015-11-20 09:59:34 -0800255 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800256 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800257 }
258
solenberg059fb442016-10-26 05:12:24 -0700259 void SetSend(bool enable) {
260 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700261 if (enable) {
262 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
263 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
264 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700265 EXPECT_CALL(apm_, ApplyConfig(testing::_));
266 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700267 }
solenberg059fb442016-10-26 05:12:24 -0700268 channel_->SetSend(enable);
269 }
270
271 void SetSendParameters(const cricket::AudioSendParameters& params) {
272 EXPECT_CALL(apm_, ApplyConfig(testing::_));
273 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
274 ASSERT_TRUE(channel_);
275 EXPECT_TRUE(channel_->SetSendParameters(params));
276 }
277
minyue6b825df2016-10-31 04:08:32 -0700278 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
279 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700280 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
281 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700282 if (enable && options) {
283 EXPECT_CALL(apm_, ApplyConfig(testing::_));
284 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
285 }
286 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700287 }
288
solenbergffbbcac2016-11-17 05:25:37 -0800289 void TestInsertDtmf(uint32_t ssrc, bool caller,
290 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700291 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000292 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700293 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000294 // send stream.
295 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800296 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000297 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000298
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700300 SetSendParameters(send_parameters_);
301 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800303 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800304 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700305 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000307
308 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700309 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800310 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000311 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800312 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313 }
314
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800316 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100318 // Test send.
319 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800320 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100321 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800322 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800323 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800324 EXPECT_EQ(codec.id, telephone_event.payload_type);
325 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100326 EXPECT_EQ(2, telephone_event.event_code);
327 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 }
329
330 // Test that send bandwidth is set correctly.
331 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000332 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
333 // |expected_result| is the expected result from SetMaxSendBandwidth().
334 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700335 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
336 int max_bitrate,
337 bool expected_result,
338 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200339 cricket::AudioSendParameters parameters;
340 parameters.codecs.push_back(codec);
341 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700342 if (expected_result) {
343 SetSendParameters(parameters);
344 } else {
345 EXPECT_FALSE(channel_->SetSendParameters(parameters));
346 }
solenberg2100c0b2017-03-01 11:29:29 -0800347 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000348 }
349
skvlade0d46372016-04-07 22:59:22 -0700350 // Sets the per-stream maximum bitrate limit for the specified SSRC.
351 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700352 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700353 EXPECT_EQ(1UL, parameters.encodings.size());
354
deadbeefe702b302017-02-04 12:09:01 -0800355 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700356 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700357 }
358
solenberg059fb442016-10-26 05:12:24 -0700359 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700360 cricket::AudioSendParameters send_parameters;
361 send_parameters.codecs.push_back(codec);
362 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700363 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700364 }
365
minyue7a973442016-10-20 03:27:12 -0700366 void CheckSendCodec(int32_t ssrc,
367 const char expected_name[],
368 int expected_channels,
369 int expected_bitrate) {
370 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
371 EXPECT_STREQ(expected_name, codec.plname);
372 EXPECT_EQ(expected_channels, codec.channels);
373 EXPECT_EQ(expected_bitrate, codec.rate);
374 }
375
376 int GetOpusMaxPlaybackRate(int32_t ssrc) {
377 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
378 }
379
380 bool GetOpusDtx(int32_t ssrc) {
381 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
382 }
383
384 bool GetCodecFec(int32_t ssrc) {
385 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
386 }
387
skvlade0d46372016-04-07 22:59:22 -0700388 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700389 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
390 }
391
392 int GetCodecPacSize(int32_t ssrc) {
393 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700394 }
395
minyue6b825df2016-10-31 04:08:32 -0700396 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
397 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
401 int global_max,
402 int stream_max,
403 bool expected_result,
404 int expected_codec_bitrate) {
405 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800406 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700407
408 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700409 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800410 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700411
412 // Verify that reading back the parameters gives results
413 // consistent with the Set() result.
414 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800415 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700416 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
417 EXPECT_EQ(expected_result ? stream_max : -1,
418 resulting_parameters.encodings[0].max_bitrate_bps);
419
420 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800421 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700422 }
423
stefan13f1a0a2016-11-30 07:22:58 -0800424 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
425 int expected_min_bitrate_bps,
426 const char* start_bitrate_kbps,
427 int expected_start_bitrate_bps,
428 const char* max_bitrate_kbps,
429 int expected_max_bitrate_bps) {
430 EXPECT_TRUE(SetupSendStream());
431 auto& codecs = send_parameters_.codecs;
432 codecs.clear();
433 codecs.push_back(kOpusCodec);
434 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
436 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
437 SetSendParameters(send_parameters_);
438
439 EXPECT_EQ(expected_min_bitrate_bps,
440 call_.GetConfig().bitrate_config.min_bitrate_bps);
441 EXPECT_EQ(expected_start_bitrate_bps,
442 call_.GetConfig().bitrate_config.start_bitrate_bps);
443 EXPECT_EQ(expected_max_bitrate_bps,
444 call_.GetConfig().bitrate_config.max_bitrate_bps);
445 }
446
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000447 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700448 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
453 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(
455 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700461 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800462 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 // Ensure extension is set properly.
465 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700466 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700467 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
solenberg7add0582015-11-20 09:59:34 -0800472 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800474 cricket::StreamParams::CreateLegacy(kSsrcY)));
475 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
476 call_.GetAudioSendStream(kSsrcY));
477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200482 send_parameters_.codecs.push_back(kPcmuCodec);
483 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 }
488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700490 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
495 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(
497 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800498 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800502 recv_parameters_.extensions.clear();
503 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 // Ensure extension is set properly.
507 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700508 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800509 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
511 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
solenberg7add0582015-11-20 09:59:34 -0800514 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_TRUE(AddRecvStream(kSsrcY));
516 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
517 call_.GetAudioReceiveStream(kSsrcY));
518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521
522 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800523 recv_parameters_.extensions.clear();
524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000527 }
528
solenberg85a04962015-10-27 03:35:21 -0700529 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
530 webrtc::AudioSendStream::Stats stats;
531 stats.local_ssrc = 12;
532 stats.bytes_sent = 345;
533 stats.packets_sent = 678;
534 stats.packets_lost = 9012;
535 stats.fraction_lost = 34.56f;
536 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800537 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700538 stats.ext_seqnum = 789;
539 stats.jitter_ms = 12;
540 stats.rtt_ms = 345;
541 stats.audio_level = 678;
542 stats.aec_quality_min = 9.01f;
543 stats.echo_delay_median_ms = 234;
544 stats.echo_delay_std_ms = 567;
545 stats.echo_return_loss = 890;
546 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700547 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800548 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700549 stats.typing_noise_detected = true;
550 return stats;
551 }
552 void SetAudioSendStreamStats() {
553 for (auto* s : call_.GetAudioSendStreams()) {
554 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200555 }
solenberg85a04962015-10-27 03:35:21 -0700556 }
solenberg566ef242015-11-06 15:34:49 -0800557 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
558 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700559 const auto stats = GetAudioSendStreamStats();
560 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
561 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
562 EXPECT_EQ(info.packets_sent, stats.packets_sent);
563 EXPECT_EQ(info.packets_lost, stats.packets_lost);
564 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
565 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800566 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700567 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
568 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
569 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
570 EXPECT_EQ(info.audio_level, stats.audio_level);
571 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
572 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
573 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
574 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
575 EXPECT_EQ(info.echo_return_loss_enhancement,
576 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700577 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800578 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
579 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800580 EXPECT_EQ(info.typing_noise_detected,
581 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700582 }
583
584 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
585 webrtc::AudioReceiveStream::Stats stats;
586 stats.remote_ssrc = 123;
587 stats.bytes_rcvd = 456;
588 stats.packets_rcvd = 768;
589 stats.packets_lost = 101;
590 stats.fraction_lost = 23.45f;
591 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800592 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700593 stats.ext_seqnum = 678;
594 stats.jitter_ms = 901;
595 stats.jitter_buffer_ms = 234;
596 stats.jitter_buffer_preferred_ms = 567;
597 stats.delay_estimate_ms = 890;
598 stats.audio_level = 1234;
599 stats.expand_rate = 5.67f;
600 stats.speech_expand_rate = 8.90f;
601 stats.secondary_decoded_rate = 1.23f;
602 stats.accelerate_rate = 4.56f;
603 stats.preemptive_expand_rate = 7.89f;
604 stats.decoding_calls_to_silence_generator = 12;
605 stats.decoding_calls_to_neteq = 345;
606 stats.decoding_normal = 67890;
607 stats.decoding_plc = 1234;
608 stats.decoding_cng = 5678;
609 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700610 stats.decoding_muted_output = 3456;
611 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200612 return stats;
613 }
614 void SetAudioReceiveStreamStats() {
615 for (auto* s : call_.GetAudioReceiveStreams()) {
616 s->SetStats(GetAudioReceiveStreamStats());
617 }
618 }
619 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700620 const auto stats = GetAudioReceiveStreamStats();
621 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
622 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
623 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
624 EXPECT_EQ(info.packets_lost, stats.packets_lost);
625 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
626 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800627 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700628 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
629 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
630 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200631 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700632 stats.jitter_buffer_preferred_ms);
633 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
634 EXPECT_EQ(info.audio_level, stats.audio_level);
635 EXPECT_EQ(info.expand_rate, stats.expand_rate);
636 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
637 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
638 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
639 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200640 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700641 stats.decoding_calls_to_silence_generator);
642 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
643 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
644 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
645 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
646 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700647 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700648 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200649 }
hbos1acfbd22016-11-17 23:43:29 -0800650 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
651 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
652 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
653 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
654 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
655 codec.ToCodecParameters());
656 }
657 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
658 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
659 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
660 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
661 codec.ToCodecParameters());
662 }
663 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200664
peah8271d042016-11-22 07:24:52 -0800665 bool IsHighPassFilterEnabled() {
666 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
667 }
668
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700670 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700671 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800672 webrtc::test::MockGainControl& apm_gc_;
673 webrtc::test::MockEchoCancellation& apm_ec_;
674 webrtc::test::MockNoiseSuppression& apm_ns_;
675 webrtc::test::MockVoiceDetection& apm_vd_;
676 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700677 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200678 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700680 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700681 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200682 cricket::AudioSendParameters send_parameters_;
683 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800684 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800685 private:
686 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687};
688
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689// Tests that we can create and destroy a channel.
690TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700691 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692}
693
solenberg31fec402016-05-06 02:13:12 -0700694// Test that we can add a send stream and that it has the correct defaults.
695TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
696 EXPECT_TRUE(SetupChannel());
697 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800698 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
699 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
700 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700701 EXPECT_EQ("", config.rtp.c_name);
702 EXPECT_EQ(0u, config.rtp.extensions.size());
703 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
704 config.send_transport);
705}
706
707// Test that we can add a receive stream and that it has the correct defaults.
708TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
709 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800710 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700711 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800712 GetRecvStreamConfig(kSsrcX);
713 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700714 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
715 EXPECT_FALSE(config.rtp.transport_cc);
716 EXPECT_EQ(0u, config.rtp.extensions.size());
717 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
718 config.rtcp_send_transport);
719 EXPECT_EQ("", config.sync_group);
720}
721
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700723// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700724// TODO(ossu): This test should move into a separate builtin audio codecs
725// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700726TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700727 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 ASSERT_FALSE(codecs.empty());
729 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
730 EXPECT_EQ(48000, codecs[0].clockrate);
731 EXPECT_EQ(2, codecs[0].channels);
732 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733}
734
stefanba4c0e42016-02-04 04:12:24 -0800735TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700736 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800737 bool opus_found = false;
738 for (cricket::AudioCodec codec : codecs) {
739 if (codec.name == "opus") {
740 EXPECT_TRUE(HasTransportCc(codec));
741 opus_found = true;
742 }
743 }
744 EXPECT_TRUE(opus_found);
745}
746
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747// Tests that we can find codecs by name or id, and that we interpret the
748// clockrate and bitrate fields properly.
749TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
750 cricket::AudioCodec codec;
751 webrtc::CodecInst codec_inst;
752 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800753 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800755 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000756 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800757 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
758 &codec_inst));
759 // Find telephone-event with explicit clockrate and 0 bitrate.
760 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800761 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762 // Find ISAC with a different payload id.
763 codec = kIsacCodec;
764 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800765 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766 EXPECT_EQ(codec.id, codec_inst.pltype);
767 // Find PCMU with a 0 clockrate.
768 codec = kPcmuCodec;
769 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800770 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771 EXPECT_EQ(codec.id, codec_inst.pltype);
772 EXPECT_EQ(8000, codec_inst.plfreq);
773 // Find PCMU with a 0 bitrate.
774 codec = kPcmuCodec;
775 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800776 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777 EXPECT_EQ(codec.id, codec_inst.pltype);
778 EXPECT_EQ(64000, codec_inst.rate);
779 // Find ISAC with an explicit bitrate.
780 codec = kIsacCodec;
781 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800782 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 EXPECT_EQ(codec.id, codec_inst.pltype);
784 EXPECT_EQ(32000, codec_inst.rate);
785}
786
787// Test that we set our inbound codecs properly, including changing PT.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200790 cricket::AudioRecvParameters parameters;
791 parameters.codecs.push_back(kIsacCodec);
792 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800793 parameters.codecs.push_back(kTelephoneEventCodec1);
794 parameters.codecs.push_back(kTelephoneEventCodec2);
795 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 parameters.codecs[2].id = 126;
797 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800798 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700799 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
800 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
801 {{0, {"PCMU", 8000, 1}},
802 {106, {"ISAC", 16000, 1}},
803 {126, {"telephone-event", 8000, 1}},
804 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805}
806
807// Test that we fail to set an unknown inbound codec.
808TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700809 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 cricket::AudioRecvParameters parameters;
811 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700812 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814}
815
816// Test that we fail if we have duplicate types in the inbound list.
817TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700818 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200819 cricket::AudioRecvParameters parameters;
820 parameters.codecs.push_back(kIsacCodec);
821 parameters.codecs.push_back(kCn16000Codec);
822 parameters.codecs[1].id = kIsacCodec.id;
823 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS without stereo parameters.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800834 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700835 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
836 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
837 {{0, {"PCMU", 8000, 1}},
838 {103, {"ISAC", 16000, 1}},
839 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840}
841
842// Test that we can decode OPUS with stereo = 0.
843TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700844 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 cricket::AudioRecvParameters parameters;
846 parameters.codecs.push_back(kIsacCodec);
847 parameters.codecs.push_back(kPcmuCodec);
848 parameters.codecs.push_back(kOpusCodec);
849 parameters.codecs[2].params["stereo"] = "0";
850 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800851 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700852 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
853 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
854 {{0, {"PCMU", 8000, 1}},
855 {103, {"ISAC", 16000, 1}},
856 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
859// Test that we can decode OPUS with stereo = 1.
860TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700861 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200862 cricket::AudioRecvParameters parameters;
863 parameters.codecs.push_back(kIsacCodec);
864 parameters.codecs.push_back(kPcmuCodec);
865 parameters.codecs.push_back(kOpusCodec);
866 parameters.codecs[2].params["stereo"] = "1";
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800868 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700869 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
870 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
871 {{0, {"PCMU", 8000, 1}},
872 {103, {"ISAC", 16000, 1}},
873 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874}
875
876// Test that changes to recv codecs are applied to all streams.
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
881 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800882 parameters.codecs.push_back(kTelephoneEventCodec1);
883 parameters.codecs.push_back(kTelephoneEventCodec2);
884 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 parameters.codecs[2].id = 126;
886 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700887 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
888 EXPECT_TRUE(AddRecvStream(ssrc));
889 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
890 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
891 {{0, {"PCMU", 8000, 1}},
892 {106, {"ISAC", 16000, 1}},
893 {126, {"telephone-event", 8000, 1}},
894 {107, {"telephone-event", 32000, 1}}})));
895 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
898TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700899 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200900 cricket::AudioRecvParameters parameters;
901 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800902 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
solenberg2100c0b2017-03-01 11:29:29 -0800905 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800906 ASSERT_EQ(1, dm.count(106));
907 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908}
909
910// Test that we can apply the same set of codecs again while playing.
911TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700912 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 cricket::AudioRecvParameters parameters;
914 parameters.codecs.push_back(kIsacCodec);
915 parameters.codecs.push_back(kCn16000Codec);
916 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700917 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
920 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 parameters.codecs[0].id = 127;
922 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
926// Test that we can add a codec while playing.
927TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700928 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 parameters.codecs.push_back(kCn16000Codec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700933 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200935 parameters.codecs.push_back(kOpusCodec);
936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800937 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800939 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
941}
942
943TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700944 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000946 // Test that when autobw is enabled, bitrate is kept as the default
947 // value. autobw is enabled for the following tests because the target
948 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
950 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700951 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952
953 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700954 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700957 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958}
959
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000960TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700961 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000963 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
965 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700966 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
967 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
968 // Rates above the max (56000) should be capped.
969 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700972 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
973 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
974 // Rates above the max (510000) should be capped.
975 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976}
977
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000978TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700979 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980
981 // Test that we can only set a maximum bitrate for a fixed-rate codec
982 // if it's bigger than the fixed rate.
983
984 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700985 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
986 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
987 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
988 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
989 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
991 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000992}
993
994TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700995 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200996 const int kDesiredBitrate = 128000;
997 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700998 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200999 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001000 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001001
1002 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001003 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001004
solenberg2100c0b2017-03-01 11:29:29 -08001005 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001006}
1007
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001008// Test that bitrate cannot be set for CBR codecs.
1009// Bitrate is ignored if it is higher than the fixed bitrate.
1010// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001011TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001012 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013
1014 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001015 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001016 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001017
1018 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001019 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001020 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001021
1022 send_parameters_.max_bandwidth_bps = 128;
1023 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001024 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025}
1026
skvlade0d46372016-04-07 22:59:22 -07001027// Test that the per-stream bitrate limit and the global
1028// bitrate limit both apply.
1029TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1030 EXPECT_TRUE(SetupSendStream());
1031
1032 // opus, default bitrate == 64000.
1033 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1034 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1035 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1036 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1037
1038 // CBR codecs allow both maximums to exceed the bitrate.
1039 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1040 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1041 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1042 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1043
1044 // CBR codecs don't allow per stream maximums to be too low.
1045 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1046 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1047}
1048
1049// Test that an attempt to set RtpParameters for a stream that does not exist
1050// fails.
1051TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1052 EXPECT_TRUE(SetupChannel());
1053 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001054 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001055 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1056
1057 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001058 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001059}
1060
1061TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001062 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001063 // This test verifies that setting RtpParameters succeeds only if
1064 // the structure contains exactly one encoding.
1065 // TODO(skvlad): Update this test when we start supporting setting parameters
1066 // for each encoding individually.
1067
1068 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001069 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001070 // Two or more encodings should result in failure.
1071 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001072 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001073 // Zero encodings should also fail.
1074 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001076}
1077
1078// Changing the SSRC through RtpParameters is not allowed.
1079TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1080 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001082 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001084}
1085
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001087// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001088TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1089 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001090 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001091 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001093 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094 ASSERT_EQ(1u, parameters.encodings.size());
1095 ASSERT_TRUE(parameters.encodings[0].active);
1096 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001097 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1098 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099
1100 // Now change it back to active and verify we resume sending.
1101 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001102 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1103 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001104}
1105
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001106// Test that SetRtpSendParameters configures the correct encoding channel for
1107// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001108TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1109 SetupForMultiSendStream();
1110 // Create send streams.
1111 for (uint32_t ssrc : kSsrcs4) {
1112 EXPECT_TRUE(
1113 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1114 }
1115 // Configure one stream to be limited by the stream config, another to be
1116 // limited by the global max, and the third one with no per-stream limit
1117 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001118 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001119 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1120 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1121 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1122
1123 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1124 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1125 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1126
1127 // Remove the global cap; the streams should switch to their respective
1128 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001129 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001130 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1131 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1132 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1133}
1134
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001135// Test that GetRtpSendParameters returns the currently configured codecs.
1136TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137 EXPECT_TRUE(SetupSendStream());
1138 cricket::AudioSendParameters parameters;
1139 parameters.codecs.push_back(kIsacCodec);
1140 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001141 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001144 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001145 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1146 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147}
1148
deadbeefcb443432016-12-12 11:12:36 -08001149// Test that GetRtpSendParameters returns an SSRC.
1150TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1151 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001152 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001153 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001154 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001155}
1156
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001159 EXPECT_TRUE(SetupSendStream());
1160 cricket::AudioSendParameters parameters;
1161 parameters.codecs.push_back(kIsacCodec);
1162 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001163 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001164
solenberg2100c0b2017-03-01 11:29:29 -08001165 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001166
1167 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001168 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001169
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001170 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001171 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1172 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001173}
1174
minyuececec102017-03-27 13:04:25 -07001175// Test that max_bitrate_bps in send stream config gets updated correctly when
1176// SetRtpSendParameters is called.
1177TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1178 webrtc::test::ScopedFieldTrials override_field_trials(
1179 "WebRTC-Audio-SendSideBwe/Enabled/");
1180 EXPECT_TRUE(SetupSendStream());
1181 cricket::AudioSendParameters send_parameters;
1182 send_parameters.codecs.push_back(kOpusCodec);
1183 SetSendParameters(send_parameters);
1184
1185 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1186 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1187 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1188
1189 constexpr int kMaxBitrateBps = 6000;
1190 rtp_parameters.encodings[0].max_bitrate_bps =
1191 rtc::Optional<int>(kMaxBitrateBps);
1192 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1193
1194 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1195 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1196}
1197
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001198// Test that GetRtpReceiveParameters returns the currently configured codecs.
1199TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1200 EXPECT_TRUE(SetupRecvStream());
1201 cricket::AudioRecvParameters parameters;
1202 parameters.codecs.push_back(kIsacCodec);
1203 parameters.codecs.push_back(kPcmuCodec);
1204 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1205
1206 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001207 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001208 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1209 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1210 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1211}
1212
deadbeefcb443432016-12-12 11:12:36 -08001213// Test that GetRtpReceiveParameters returns an SSRC.
1214TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1215 EXPECT_TRUE(SetupRecvStream());
1216 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001217 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001218 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001219 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001220}
1221
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001222// Test that if we set/get parameters multiple times, we get the same results.
1223TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1224 EXPECT_TRUE(SetupRecvStream());
1225 cricket::AudioRecvParameters parameters;
1226 parameters.codecs.push_back(kIsacCodec);
1227 parameters.codecs.push_back(kPcmuCodec);
1228 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1229
1230 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001231 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001232
1233 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001234 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001235
1236 // ... And this shouldn't change the params returned by
1237 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001238 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1239 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001240}
1241
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242// Test that we apply codecs properly.
1243TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001244 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001245 cricket::AudioSendParameters parameters;
1246 parameters.codecs.push_back(kIsacCodec);
1247 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001248 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001249 parameters.codecs[0].id = 96;
1250 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001251 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001252 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001253 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001254 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001255 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1256 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1257 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1258 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001259 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001260 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001261}
1262
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001263// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1264// to apply.
1265TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001266 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001267 cricket::AudioSendParameters parameters;
1268 parameters.codecs.push_back(kIsacCodec);
1269 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001270 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001271 parameters.codecs[0].id = 96;
1272 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001273 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001274 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001275 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001276 // Calling SetSendCodec again with same codec which is already set.
1277 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001278 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001279 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001280}
1281
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001282// Verify that G722 is set with 16000 samples per second to WebRTC.
1283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001287 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001288 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001289 EXPECT_STREQ("G722", gcodec.plname);
1290 EXPECT_EQ(1, gcodec.channels);
1291 EXPECT_EQ(16000, gcodec.plfreq);
1292}
1293
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001294// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
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].clockrate = 50000;
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, SetSendCodecOpusBad0ChannelsNoStereo) {
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 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312}
1313
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001314// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001315TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001316 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001317 cricket::AudioSendParameters parameters;
1318 parameters.codecs.push_back(kOpusCodec);
1319 parameters.codecs[0].bitrate = 0;
1320 parameters.codecs[0].channels = 0;
1321 parameters.codecs[0].params["stereo"] = "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 there's no stereo, we fail.
1326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
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 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
1335// Test that if channel is 1 for opus and stereo=0, we fail.
1336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].channels = 1;
1342 parameters.codecs[0].params["stereo"] = "0";
1343 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
1346// Test that if channel is 1 for opus and stereo=1, we fail.
1347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
1352 parameters.codecs[0].channels = 1;
1353 parameters.codecs[0].params["stereo"] = "1";
1354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
1357// Test that with bitrate=0 and no stereo,
1358// channels and bitrate are 1 and 32000.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001360 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 cricket::AudioSendParameters parameters;
1362 parameters.codecs.push_back(kOpusCodec);
1363 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001364 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001365 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
1368// Test that with bitrate=0 and stereo=0,
1369// channels and bitrate are 1 and 32000.
1370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].bitrate = 0;
1375 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001376 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001377 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001378}
1379
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001380// Test that with bitrate=invalid and stereo=0,
1381// channels and bitrate are 1 and 32000.
1382TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001383 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 cricket::AudioSendParameters parameters;
1385 parameters.codecs.push_back(kOpusCodec);
1386 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001387 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001389 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001390 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001391
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001394 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001395}
1396
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397// Test that with bitrate=0 and stereo=1,
1398// channels and bitrate are 2 and 64000.
1399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].bitrate = 0;
1404 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001406 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407}
1408
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001409// Test that with bitrate=invalid and stereo=1,
1410// channels and bitrate are 2 and 64000.
1411TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001412 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 cricket::AudioSendParameters parameters;
1414 parameters.codecs.push_back(kOpusCodec);
1415 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001416 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001419 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001420
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001422 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001423 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001424}
1425
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426// Test that with bitrate=N and stereo unset,
1427// channels and bitrate are 1 and N.
1428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001433 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001434 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435 EXPECT_EQ(111, gcodec.pltype);
1436 EXPECT_EQ(96000, gcodec.rate);
1437 EXPECT_STREQ("opus", gcodec.plname);
1438 EXPECT_EQ(1, gcodec.channels);
1439 EXPECT_EQ(48000, gcodec.plfreq);
1440}
1441
1442// Test that with bitrate=N and stereo=0,
1443// channels and bitrate are 1 and N.
1444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].bitrate = 30000;
1449 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001451 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
1454// Test that with bitrate=N and without any parameters,
1455// channels and bitrate are 1 and N.
1456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001457 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 cricket::AudioSendParameters parameters;
1459 parameters.codecs.push_back(kOpusCodec);
1460 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001462 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
1465// Test that with bitrate=N and stereo=1,
1466// channels and bitrate are 2 and N.
1467TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001468 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001469 cricket::AudioSendParameters parameters;
1470 parameters.codecs.push_back(kOpusCodec);
1471 parameters.codecs[0].bitrate = 30000;
1472 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001473 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001474 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475}
1476
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001477// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1478// Also test that the "maxaveragebitrate" can't be set to values outside the
1479// range of 6000 and 510000
1480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001485 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001486 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001487 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001488 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001489
1490 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001491 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001492 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001493 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001494
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001497 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001498}
1499
stefan13f1a0a2016-11-30 07:22:58 -08001500TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1501 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1502 200000);
1503}
1504
1505TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1506 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1507}
1508
1509TEST_F(WebRtcVoiceEngineTestFake,
1510 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1511 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1512}
1513
1514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1515 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1516}
1517
1518TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001519 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001520 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1521 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001522 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001523 SetSendParameters(send_parameters_);
1524 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1525 << "Setting max bitrate should keep previous min bitrate.";
1526 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1527 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001528 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001529}
1530
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001531// Test that we can enable NACK with opus as caller.
1532TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001533 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001534 cricket::AudioSendParameters parameters;
1535 parameters.codecs.push_back(kOpusCodec);
1536 parameters.codecs[0].AddFeedbackParam(
1537 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1538 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001539 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542}
1543
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001544// Test that we can enable NACK with opus as callee.
1545TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001546 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001547 cricket::AudioSendParameters parameters;
1548 parameters.codecs.push_back(kOpusCodec);
1549 parameters.codecs[0].AddFeedbackParam(
1550 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1551 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001554 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001556
1557 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001558 cricket::StreamParams::CreateLegacy(kSsrcX)));
1559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001560}
1561
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562// Test that we can enable NACK on receive streams.
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001564 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001565 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].AddFeedbackParam(
1569 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1570 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1572 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1575 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576}
1577
1578// Test that we can disable NACK.
1579TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001580 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001581 cricket::AudioSendParameters parameters;
1582 parameters.codecs.push_back(kOpusCodec);
1583 parameters.codecs[0].AddFeedbackParam(
1584 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1585 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001587 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 parameters.codecs.clear();
1590 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001591 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001592 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
1595// Test that we can disable NACK on receive streams.
1596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 cricket::AudioSendParameters parameters;
1600 parameters.codecs.push_back(kOpusCodec);
1601 parameters.codecs[0].AddFeedbackParam(
1602 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1603 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001605 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1606 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 parameters.codecs.clear();
1609 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001611 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1612 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613}
1614
1615// Test that NACK is enabled on a new receive stream.
1616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001617 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001618 cricket::AudioSendParameters parameters;
1619 parameters.codecs.push_back(kIsacCodec);
1620 parameters.codecs.push_back(kCn16000Codec);
1621 parameters.codecs[0].AddFeedbackParam(
1622 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1623 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001625 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_TRUE(AddRecvStream(kSsrcY));
1628 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1629 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1630 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001631}
1632
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001633// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001634TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001635 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001636 cricket::AudioSendParameters parameters;
1637 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001638 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001639 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001640}
1641
1642// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001644 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001645 cricket::AudioSendParameters parameters;
1646 parameters.codecs.push_back(kOpusCodec);
1647 parameters.codecs[0].bitrate = 0;
1648 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001649 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001650 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001651}
1652
1653// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001654TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001655 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001656 cricket::AudioSendParameters parameters;
1657 parameters.codecs.push_back(kOpusCodec);
1658 parameters.codecs[0].bitrate = 0;
1659 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 EXPECT_TRUE(GetCodecFec(kSsrcX));
1662 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001663}
1664
1665// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001666TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001667 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001668 cricket::AudioSendParameters parameters;
1669 parameters.codecs.push_back(kOpusCodec);
1670 parameters.codecs[0].bitrate = 0;
1671 parameters.codecs[0].params["stereo"] = "1";
1672 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001674 EXPECT_TRUE(GetCodecFec(kSsrcX));
1675 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001676}
1677
1678// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001679TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001680 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 cricket::AudioSendParameters parameters;
1682 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001684 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001685}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001686
1687// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1688TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
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(kIsacCodec);
1692 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001695}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001696
1697// Test that Opus FEC status can be changed.
1698TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 cricket::AudioSendParameters parameters;
1701 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001703 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001704
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001706 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001707 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001708}
1709
stefanba4c0e42016-02-04 04:12:24 -08001710TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001711 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001712 cricket::AudioSendParameters send_parameters;
1713 send_parameters.codecs.push_back(kOpusCodec);
1714 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001716
1717 cricket::AudioRecvParameters recv_parameters;
1718 recv_parameters.codecs.push_back(kIsacCodec);
1719 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001720 EXPECT_TRUE(AddRecvStream(kSsrcX));
1721 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001722 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001723 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001724
ossudedfd282016-06-14 07:12:39 -07001725 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001727 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001728 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001729 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001730}
1731
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001732// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1733TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001734 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters parameters;
1736 parameters.codecs.push_back(kOpusCodec);
1737 parameters.codecs[0].bitrate = 0;
1738 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001740 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1741 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001742
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001745 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001746}
1747
1748// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1749TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001750 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 cricket::AudioSendParameters parameters;
1752 parameters.codecs.push_back(kOpusCodec);
1753 parameters.codecs[0].bitrate = 0;
1754 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001756 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1757 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001758
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001761 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001762}
1763
1764// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1765TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kOpusCodec);
1769 parameters.codecs[0].bitrate = 0;
1770 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001771 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001772 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1773 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001774
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001776 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001777 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001778}
1779
1780// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1781TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001782 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001783 cricket::AudioSendParameters parameters;
1784 parameters.codecs.push_back(kOpusCodec);
1785 parameters.codecs[0].bitrate = 0;
1786 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001788 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1789 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001790
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001792 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001793 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001794}
1795
1796// Test 24000 < maxplaybackrate triggers Opus full band mode.
1797TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001798 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001799 cricket::AudioSendParameters parameters;
1800 parameters.codecs.push_back(kOpusCodec);
1801 parameters.codecs[0].bitrate = 0;
1802 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001804 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1805 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001806
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001807 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001808 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001809 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001810}
1811
1812// Test Opus that without maxplaybackrate, default playback rate is used.
1813TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001814 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 cricket::AudioSendParameters parameters;
1816 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001818 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001819}
1820
1821// Test the with non-Opus, maxplaybackrate has no effect.
1822TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
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(kIsacCodec);
1826 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001827 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001828 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001829}
1830
1831// Test maxplaybackrate can be set on two streams.
1832TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001833 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 cricket::AudioSendParameters parameters;
1835 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001837 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001838
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001841 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001842
solenberg2100c0b2017-03-01 11:29:29 -08001843 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1844 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001845}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001846
Minyue Li7100dcd2015-03-27 05:05:59 +01001847// Test that with usedtx=0, Opus DTX is off.
1848TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
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"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001854 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001855}
1856
1857// Test that with usedtx=1, Opus DTX is on.
1858TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
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";
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001864 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001865}
1866
1867// Test that usedtx=1 works with stereo Opus.
1868TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 cricket::AudioSendParameters parameters;
1871 parameters.codecs.push_back(kOpusCodec);
1872 parameters.codecs[0].params["usedtx"] = "1";
1873 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001875 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001876}
1877
1878// Test that usedtx=1 does not work with non Opus.
1879TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 cricket::AudioSendParameters parameters;
1882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001884 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001885 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001886}
1887
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001888// Test that we can switch back and forth between Opus and ISAC with CN.
1889TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001890 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001891
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 cricket::AudioSendParameters opus_parameters;
1893 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001894 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001895 {
solenberg2100c0b2017-03-01 11:29:29 -08001896 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(111, gcodec.pltype);
1898 EXPECT_STREQ("opus", gcodec.plname);
1899 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters isac_parameters;
1902 isac_parameters.codecs.push_back(kIsacCodec);
1903 isac_parameters.codecs.push_back(kCn16000Codec);
1904 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001905 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001906 {
solenberg2100c0b2017-03-01 11:29:29 -08001907 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001908 EXPECT_EQ(103, gcodec.pltype);
1909 EXPECT_STREQ("ISAC", gcodec.plname);
1910 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001911
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001913 {
solenberg2100c0b2017-03-01 11:29:29 -08001914 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001915 EXPECT_EQ(111, gcodec.pltype);
1916 EXPECT_STREQ("opus", gcodec.plname);
1917 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001918}
1919
1920// Test that we handle various ways of specifying bitrate.
1921TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001922 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 cricket::AudioSendParameters parameters;
1924 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001925 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001926 {
solenberg2100c0b2017-03-01 11:29:29 -08001927 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001928 EXPECT_EQ(103, gcodec.pltype);
1929 EXPECT_STREQ("ISAC", gcodec.plname);
1930 EXPECT_EQ(32000, gcodec.rate);
1931 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001932
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001933 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001934 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001935 {
solenberg2100c0b2017-03-01 11:29:29 -08001936 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001937 EXPECT_EQ(103, gcodec.pltype);
1938 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001939 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001940 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001943 {
solenberg2100c0b2017-03-01 11:29:29 -08001944 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001945 EXPECT_EQ(103, gcodec.pltype);
1946 EXPECT_STREQ("ISAC", gcodec.plname);
1947 EXPECT_EQ(28000, gcodec.rate);
1948 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001952 {
solenberg2100c0b2017-03-01 11:29:29 -08001953 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001954 EXPECT_EQ(0, gcodec.pltype);
1955 EXPECT_STREQ("PCMU", gcodec.plname);
1956 EXPECT_EQ(64000, gcodec.rate);
1957 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 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(0, gcodec.pltype);
1964 EXPECT_STREQ("PCMU", gcodec.plname);
1965 EXPECT_EQ(64000, gcodec.rate);
1966 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001968 parameters.codecs[0] = kOpusCodec;
1969 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001971 {
solenberg2100c0b2017-03-01 11:29:29 -08001972 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001973 EXPECT_EQ(111, gcodec.pltype);
1974 EXPECT_STREQ("opus", gcodec.plname);
1975 EXPECT_EQ(32000, gcodec.rate);
1976 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001977}
1978
Brave Yao5225dd82015-03-26 07:39:19 +08001979// Test that we could set packet size specified in kCodecParamPTime.
1980TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001981 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 cricket::AudioSendParameters parameters;
1983 parameters.codecs.push_back(kOpusCodec);
1984 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001987
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001988 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001989 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001990 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001991
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001992 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001993 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001994 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001995
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001996 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1997 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001999 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002000 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08002001
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002002 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
2003 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002005 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002006 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08002007}
2008
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002009// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002010TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002011 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 cricket::AudioSendParameters parameters;
2013 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002014}
2015
2016// Test that we can set send codecs even with telephone-event codec as the first
2017// one on the list.
2018TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002019 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002020 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002021 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002022 parameters.codecs.push_back(kIsacCodec);
2023 parameters.codecs.push_back(kPcmuCodec);
2024 parameters.codecs[0].id = 98; // DTMF
2025 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002026 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002027 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002028 EXPECT_EQ(96, gcodec.pltype);
2029 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002030 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002031}
2032
solenberg31642aa2016-03-14 08:00:37 -07002033// Test that payload type range is limited for telephone-event codec.
2034TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002035 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002036 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002037 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002038 parameters.codecs.push_back(kIsacCodec);
2039 parameters.codecs[0].id = 0; // DTMF
2040 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002041 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002042 EXPECT_TRUE(channel_->CanInsertDtmf());
2043 parameters.codecs[0].id = 128; // DTMF
2044 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2045 EXPECT_FALSE(channel_->CanInsertDtmf());
2046 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002047 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002048 EXPECT_TRUE(channel_->CanInsertDtmf());
2049 parameters.codecs[0].id = -1; // DTMF
2050 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2051 EXPECT_FALSE(channel_->CanInsertDtmf());
2052}
2053
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002054// Test that we can set send codecs even with CN codec as the first
2055// one on the list.
2056TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002057 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002058 cricket::AudioSendParameters parameters;
2059 parameters.codecs.push_back(kCn16000Codec);
2060 parameters.codecs.push_back(kIsacCodec);
2061 parameters.codecs.push_back(kPcmuCodec);
2062 parameters.codecs[0].id = 98; // wideband CN
2063 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002064 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002065 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002066 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2067 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2068 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2069 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002070}
2071
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002072// Test that we set VAD and DTMF types correctly as caller.
2073TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002074 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002075 cricket::AudioSendParameters parameters;
2076 parameters.codecs.push_back(kIsacCodec);
2077 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002078 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002079 parameters.codecs.push_back(kCn16000Codec);
2080 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002081 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002082 parameters.codecs[0].id = 96;
2083 parameters.codecs[2].id = 97; // wideband CN
2084 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002085 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002086 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002087 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2088 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2089 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2090 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2091 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2092 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002093 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002094}
2095
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002096// Test that we set VAD and DTMF types correctly as callee.
2097TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002098 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002099 cricket::AudioSendParameters parameters;
2100 parameters.codecs.push_back(kIsacCodec);
2101 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002102 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002103 parameters.codecs.push_back(kCn16000Codec);
2104 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002105 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002106 parameters.codecs[0].id = 96;
2107 parameters.codecs[2].id = 97; // wideband CN
2108 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002109 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002110 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002111 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002112
solenberg2100c0b2017-03-01 11:29:29 -08002113 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002114 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2115 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2116 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2117 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2118 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2119 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002120 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002121}
2122
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002123// Test that we only apply VAD if we have a CN codec that matches the
2124// send codec clockrate.
2125TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002126 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002127 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002128 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002129 parameters.codecs.push_back(kIsacCodec);
2130 parameters.codecs.push_back(kCn16000Codec);
2131 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002132 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002133 {
solenberg2100c0b2017-03-01 11:29:29 -08002134 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002135 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2136 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2137 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2138 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2139 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2140 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002141 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002142 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002143 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002144 {
solenberg2100c0b2017-03-01 11:29:29 -08002145 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002146 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2147 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2148 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002149 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002150 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002151 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002152 {
solenberg2100c0b2017-03-01 11:29:29 -08002153 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002154 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2155 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2156 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2157 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2158 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2159 }
Brave Yao5225dd82015-03-26 07:39:19 +08002160 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002162 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002163 {
solenberg2100c0b2017-03-01 11:29:29 -08002164 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002165 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2166 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2167 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168}
2169
2170// Test that we perform case-insensitive matching of codec names.
2171TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002172 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002173 cricket::AudioSendParameters parameters;
2174 parameters.codecs.push_back(kIsacCodec);
2175 parameters.codecs.push_back(kPcmuCodec);
2176 parameters.codecs.push_back(kCn16000Codec);
2177 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002178 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002179 parameters.codecs[0].name = "iSaC";
2180 parameters.codecs[0].id = 96;
2181 parameters.codecs[2].id = 97; // wideband CN
2182 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002184 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002185 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2186 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2187 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2188 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2189 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2190 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002191 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002192}
2193
stefanba4c0e42016-02-04 04:12:24 -08002194class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2195 public:
2196 WebRtcVoiceEngineWithSendSideBweTest()
2197 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2198};
2199
2200TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2201 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002202 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002203 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002204 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2205 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2206 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002207 extension.id);
2208 return;
2209 }
2210 }
2211 FAIL() << "Transport sequence number extension not in header-extension list.";
2212}
2213
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002214// Test support for audio level header extension.
2215TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002216 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002217}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002218TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002219 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002220}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002221
solenbergd4adce42016-11-17 06:26:52 -08002222// Test support for transport sequence number header extension.
2223TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2224 TestSetSendRtpHeaderExtensions(
2225 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002226}
solenbergd4adce42016-11-17 06:26:52 -08002227TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2228 TestSetRecvRtpHeaderExtensions(
2229 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002230}
2231
solenberg1ac56142015-10-13 03:58:19 -07002232// Test that we can create a channel and start sending on it.
2233TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002234 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
2236 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002238 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002239 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002240}
2241
2242// Test that a channel will send if and only if it has a source and is enabled
2243// for sending.
2244TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002245 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002246 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002247 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002248 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002249 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2250 SetAudioSend(kSsrcX, true, &fake_source_);
2251 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2252 SetAudioSend(kSsrcX, true, nullptr);
2253 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002254}
2255
solenberg94218532016-06-16 10:53:22 -07002256// Test that a channel is muted/unmuted.
2257TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2258 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002259 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002260 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2261 SetAudioSend(kSsrcX, true, nullptr);
2262 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2263 SetAudioSend(kSsrcX, false, nullptr);
2264 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002265}
2266
solenberg6d6e7c52016-04-13 09:07:30 -07002267// Test that SetSendParameters() does not alter a stream's send state.
2268TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2269 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002270 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002271
2272 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002273 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002274 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002275
2276 // Changing RTP header extensions will recreate the AudioSendStream.
2277 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002278 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002279 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002280 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002281
2282 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002283 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002284 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002285
2286 // Changing RTP header extensions will recreate the AudioSendStream.
2287 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002288 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002290}
2291
solenberg1ac56142015-10-13 03:58:19 -07002292// Test that we can create a channel and start playing out on it.
2293TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002294 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002295 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002296 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002298 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300}
2301
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002302// Test that we can add and remove send streams.
2303TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2304 SetupForMultiSendStream();
2305
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002306 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002307 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002308
solenbergc96df772015-10-21 13:01:53 -07002309 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002310 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002311 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002312 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002313 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002314 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002315 }
tfarina5237aaf2015-11-10 23:44:30 -08002316 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002317
solenbergc96df772015-10-21 13:01:53 -07002318 // Delete the send streams.
2319 for (uint32_t ssrc : kSsrcs4) {
2320 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002321 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002322 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 }
solenbergc96df772015-10-21 13:01:53 -07002324 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002325}
2326
2327// Test SetSendCodecs correctly configure the codecs in all send streams.
2328TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2329 SetupForMultiSendStream();
2330
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002331 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002332 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002333 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002334 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002335 }
2336
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002337 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002338 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002339 parameters.codecs.push_back(kIsacCodec);
2340 parameters.codecs.push_back(kCn16000Codec);
2341 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002342 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002343
2344 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002345 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002346 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2347 const auto& send_codec_spec =
2348 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2349 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2350 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2351 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2352 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2353 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002354 }
2355
minyue7a973442016-10-20 03:27:12 -07002356 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002357 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002358 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002359 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002360 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2361 const auto& send_codec_spec =
2362 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2363 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002364 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002365 }
2366}
2367
2368// Test we can SetSend on all send streams correctly.
2369TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2370 SetupForMultiSendStream();
2371
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002372 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002373 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002374 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002375 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002376 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002377 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002378 }
2379
2380 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002381 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002382 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002383 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002384 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002385 }
2386
2387 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002388 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002389 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002390 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002391 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002392 }
2393}
2394
2395// Test we can set the correct statistics on all send streams.
2396TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2397 SetupForMultiSendStream();
2398
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002399 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002400 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002401 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002402 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002403 }
solenberg85a04962015-10-27 03:35:21 -07002404
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002405 // Create a receive stream to check that none of the send streams end up in
2406 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002407 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002408
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002409 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002410 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002411 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002412 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002413
solenberg85a04962015-10-27 03:35:21 -07002414 // Check stats for the added streams.
2415 {
2416 cricket::VoiceMediaInfo info;
2417 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002418
solenberg85a04962015-10-27 03:35:21 -07002419 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002420 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002421 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002422 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002423 }
hbos1acfbd22016-11-17 23:43:29 -08002424 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002425
2426 // We have added one receive stream. We should see empty stats.
2427 EXPECT_EQ(info.receivers.size(), 1u);
2428 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002429 }
solenberg1ac56142015-10-13 03:58:19 -07002430
solenberg2100c0b2017-03-01 11:29:29 -08002431 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002432 {
2433 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002434 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002435 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002436 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002437 EXPECT_EQ(0u, info.receivers.size());
2438 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002439
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002440 // Deliver a new packet - a default receive stream should be created and we
2441 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002442 {
2443 cricket::VoiceMediaInfo info;
2444 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2445 SetAudioReceiveStreamStats();
2446 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002447 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002448 EXPECT_EQ(1u, info.receivers.size());
2449 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002450 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002451 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002452}
2453
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002454// Test that we can add and remove receive streams, and do proper send/playout.
2455// We can receive on multiple streams while sending one stream.
2456TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002457 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002458
solenberg1ac56142015-10-13 03:58:19 -07002459 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002460 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002461 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462
solenberg1ac56142015-10-13 03:58:19 -07002463 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002465 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002466 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467
solenberg1ac56142015-10-13 03:58:19 -07002468 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002469 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470
2471 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002472 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2473 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2474 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475
2476 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002477 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002478 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479
2480 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002481 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002482 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2483 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484
aleloi84ef6152016-08-04 05:28:21 -07002485 // Restart playout and make sure recv streams are played out.
2486 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002487 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2488 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489
aleloi84ef6152016-08-04 05:28:21 -07002490 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002491 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2492 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002493}
2494
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002496// and start sending on it.
2497TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002498 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002499 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2500 EXPECT_CALL(apm_gc_,
2501 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002502 SetSendParameters(send_parameters_);
2503 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002504 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002505 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002506 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507}
2508
wu@webrtc.org97077a32013-10-25 21:18:33 +00002509TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002510 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002511 EXPECT_CALL(adm_,
2512 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002513 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2514 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002515 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2516 send_parameters_.options.tx_agc_digital_compression_gain =
2517 rtc::Optional<uint16_t>(9);
2518 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2519 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002520 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2521 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2522 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002523 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002524
2525 // Check interaction with adjust_agc_delta. Both should be respected, for
2526 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002527 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002528 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002529 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002530}
2531
wu@webrtc.org97077a32013-10-25 21:18:33 +00002532TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002533 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002534 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2535 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002536 send_parameters_.options.recording_sample_rate =
2537 rtc::Optional<uint32_t>(48000);
2538 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002539 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002540}
2541
minyue6b825df2016-10-31 04:08:32 -07002542TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2543 EXPECT_TRUE(SetupSendStream());
2544 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2545 send_parameters_.options.audio_network_adaptor_config =
2546 rtc::Optional<std::string>("1234");
2547 SetSendParameters(send_parameters_);
2548 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002549 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002550}
2551
2552TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2553 EXPECT_TRUE(SetupSendStream());
2554 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2555 send_parameters_.options.audio_network_adaptor_config =
2556 rtc::Optional<std::string>("1234");
2557 SetSendParameters(send_parameters_);
2558 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002559 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002560 const int initial_num = call_.GetNumCreatedSendStreams();
2561 cricket::AudioOptions options;
2562 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002563 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002564 // AudioSendStream expected to be recreated.
2565 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002566 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002567}
2568
2569TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2570 EXPECT_TRUE(SetupSendStream());
2571 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2572 send_parameters_.options.audio_network_adaptor_config =
2573 rtc::Optional<std::string>("1234");
2574 SetSendParameters(send_parameters_);
2575 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002576 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002577 const int initial_num = call_.GetNumCreatedSendStreams();
2578 cricket::AudioOptions options;
2579 options.audio_network_adaptor = rtc::Optional<bool>();
2580 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2581 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002582 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002583 // AudioSendStream not expected to be recreated.
2584 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2585 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002586 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002587}
2588
michaelt6672b262017-01-11 10:17:59 -08002589class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2590 : public WebRtcVoiceEngineTestFake {
2591 public:
2592 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2593 : WebRtcVoiceEngineTestFake(
2594 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2595 "Enabled/") {}
2596};
2597
2598TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2599 EXPECT_TRUE(SetupSendStream());
2600 cricket::AudioSendParameters parameters;
2601 parameters.codecs.push_back(kOpusCodec);
2602 SetSendParameters(parameters);
2603 const int initial_num = call_.GetNumCreatedSendStreams();
2604 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2605
2606 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2607 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002608 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2609 constexpr int kMinOverheadBps =
2610 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002611
2612 constexpr int kOpusMinBitrateBps = 6000;
2613 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002614 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002615 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002616 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002617 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002618
2619 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2620 parameters.options.audio_network_adaptor_config =
2621 rtc::Optional<std::string>("1234");
2622 SetSendParameters(parameters);
2623
ossu11bfc532017-02-16 05:37:06 -08002624 constexpr int kMinOverheadWithAnaBps =
2625 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002626
2627 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002628 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002629
minyuececec102017-03-27 13:04:25 -07002630 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002631 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002632}
2633
minyuececec102017-03-27 13:04:25 -07002634// This test is similar to
2635// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2636// additional field trial.
2637TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2638 SetRtpSendParameterUpdatesMaxBitrate) {
2639 EXPECT_TRUE(SetupSendStream());
2640 cricket::AudioSendParameters send_parameters;
2641 send_parameters.codecs.push_back(kOpusCodec);
2642 SetSendParameters(send_parameters);
2643
2644 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2645 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2646 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2647
2648 constexpr int kMaxBitrateBps = 6000;
2649 rtp_parameters.encodings[0].max_bitrate_bps =
2650 rtc::Optional<int>(kMaxBitrateBps);
2651 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2652
2653 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2654#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2655 constexpr int kMinOverhead = 3333;
2656#else
2657 constexpr int kMinOverhead = 6666;
2658#endif
2659 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2660}
2661
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002663// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002665 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002666 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667}
2668
2669TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2670 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002671 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002672 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002673 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002674 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002675 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002676 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002677 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002678
solenberg85a04962015-10-27 03:35:21 -07002679 // Check stats for the added streams.
2680 {
2681 cricket::VoiceMediaInfo info;
2682 EXPECT_EQ(true, channel_->GetStats(&info));
2683
2684 // We have added one send stream. We should see the stats we've set.
2685 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002686 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002687 // We have added one receive stream. We should see empty stats.
2688 EXPECT_EQ(info.receivers.size(), 1u);
2689 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2690 }
solenberg1ac56142015-10-13 03:58:19 -07002691
solenberg566ef242015-11-06 15:34:49 -08002692 // Start sending - this affects some reported stats.
2693 {
2694 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002695 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002696 EXPECT_EQ(true, channel_->GetStats(&info));
2697 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002698 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002699 }
2700
solenberg2100c0b2017-03-01 11:29:29 -08002701 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002702 {
2703 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002704 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002705 EXPECT_EQ(true, channel_->GetStats(&info));
2706 EXPECT_EQ(1u, info.senders.size());
2707 EXPECT_EQ(0u, info.receivers.size());
2708 }
solenberg1ac56142015-10-13 03:58:19 -07002709
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002710 // Deliver a new packet - a default receive stream should be created and we
2711 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002712 {
2713 cricket::VoiceMediaInfo info;
2714 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2715 SetAudioReceiveStreamStats();
2716 EXPECT_EQ(true, channel_->GetStats(&info));
2717 EXPECT_EQ(1u, info.senders.size());
2718 EXPECT_EQ(1u, info.receivers.size());
2719 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002720 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002721 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002722}
2723
2724// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002725// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002726TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002727 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002728 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2729 EXPECT_TRUE(AddRecvStream(kSsrcY));
2730 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731}
2732
2733// Test that the local SSRC is the same on sending and receiving channels if the
2734// receive channel is created before the send channel.
2735TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002736 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002737 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002739 cricket::StreamParams::CreateLegacy(kSsrcX)));
2740 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2741 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742}
2743
2744// Test that we can properly receive packets.
2745TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002746 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002747 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002749
2750 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2751 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002752}
2753
2754// Test that we can properly receive packets on multiple streams.
2755TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002756 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002757 const uint32_t ssrc1 = 1;
2758 const uint32_t ssrc2 = 2;
2759 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(ssrc1));
2761 EXPECT_TRUE(AddRecvStream(ssrc2));
2762 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002763 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002764 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002765 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002767 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768 }
mflodman3d7db262016-04-29 00:57:13 -07002769
2770 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2771 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2772 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2773
2774 EXPECT_EQ(s1.received_packets(), 0);
2775 EXPECT_EQ(s2.received_packets(), 0);
2776 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002777
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002778 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002779 EXPECT_EQ(s1.received_packets(), 0);
2780 EXPECT_EQ(s2.received_packets(), 0);
2781 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002782
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002784 EXPECT_EQ(s1.received_packets(), 1);
2785 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2786 EXPECT_EQ(s2.received_packets(), 0);
2787 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002788
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002790 EXPECT_EQ(s1.received_packets(), 1);
2791 EXPECT_EQ(s2.received_packets(), 1);
2792 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2793 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002794
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002796 EXPECT_EQ(s1.received_packets(), 1);
2797 EXPECT_EQ(s2.received_packets(), 1);
2798 EXPECT_EQ(s3.received_packets(), 1);
2799 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002800
mflodman3d7db262016-04-29 00:57:13 -07002801 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2802 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2803 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804}
2805
solenberg2100c0b2017-03-01 11:29:29 -08002806// Test that receiving on an unsignaled stream works (a stream is created).
2807TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002808 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002809 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2810
solenberg7e63ef02015-11-20 00:19:43 -08002811 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002812
2813 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002814 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2815 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002816}
2817
solenberg2100c0b2017-03-01 11:29:29 -08002818// Test that receiving N unsignaled stream works (streams will be created), and
2819// that packets are forwarded to them all.
2820TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002821 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002822 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002823 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2824
solenberg2100c0b2017-03-01 11:29:29 -08002825 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002826 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002827 rtc::SetBE32(&packet[8], ssrc);
2828 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002829
solenberg2100c0b2017-03-01 11:29:29 -08002830 // Verify we have one new stream for each loop iteration.
2831 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002832 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2833 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002834 }
mflodman3d7db262016-04-29 00:57:13 -07002835
solenberg2100c0b2017-03-01 11:29:29 -08002836 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002837 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002838 rtc::SetBE32(&packet[8], ssrc);
2839 DeliverPacket(packet, sizeof(packet));
2840
solenbergebb349d2017-03-13 05:46:15 -07002841 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002842 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2843 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2844 }
2845
2846 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2847 constexpr uint32_t kAnotherSsrc = 667;
2848 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002849 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002850
2851 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002852 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002853 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002854 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002855 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2856 EXPECT_EQ(2, streams[i]->received_packets());
2857 }
2858 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2859 EXPECT_EQ(1, streams[i]->received_packets());
2860 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002861 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002862}
2863
solenberg2100c0b2017-03-01 11:29:29 -08002864// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002865// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002866TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002867 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002868 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002869 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2870
2871 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002872 const uint32_t signaled_ssrc = 1;
2873 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002874 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002875 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002876 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2877 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002878 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002879
2880 // Note that the first unknown SSRC cannot be 0, because we only support
2881 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002882 const uint32_t unsignaled_ssrc = 7011;
2883 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002884 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002885 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2886 packet, sizeof(packet)));
2887 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2888
2889 DeliverPacket(packet, sizeof(packet));
2890 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2891
2892 rtc::SetBE32(&packet[8], signaled_ssrc);
2893 DeliverPacket(packet, sizeof(packet));
2894 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2895 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002896}
2897
solenberg4904fb62017-02-17 12:01:14 -08002898// Two tests to verify that adding a receive stream with the same SSRC as a
2899// previously added unsignaled stream will only recreate underlying stream
2900// objects if the stream parameters have changed.
2901TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2902 EXPECT_TRUE(SetupChannel());
2903
2904 // Spawn unsignaled stream with SSRC=1.
2905 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2906 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2907 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2908 sizeof(kPcmuFrame)));
2909
2910 // Verify that the underlying stream object in Call is not recreated when a
2911 // stream with SSRC=1 is added.
2912 const auto& streams = call_.GetAudioReceiveStreams();
2913 EXPECT_EQ(1, streams.size());
2914 int audio_receive_stream_id = streams.front()->id();
2915 EXPECT_TRUE(AddRecvStream(1));
2916 EXPECT_EQ(1, streams.size());
2917 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2918}
2919
2920TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2921 EXPECT_TRUE(SetupChannel());
2922
2923 // Spawn unsignaled stream with SSRC=1.
2924 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2925 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2926 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2927 sizeof(kPcmuFrame)));
2928
2929 // Verify that the underlying stream object in Call *is* recreated when a
2930 // stream with SSRC=1 is added, and which has changed stream parameters.
2931 const auto& streams = call_.GetAudioReceiveStreams();
2932 EXPECT_EQ(1, streams.size());
2933 int audio_receive_stream_id = streams.front()->id();
2934 cricket::StreamParams stream_params;
2935 stream_params.ssrcs.push_back(1);
2936 stream_params.sync_label = "sync_label";
2937 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2938 EXPECT_EQ(1, streams.size());
2939 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2940}
2941
solenberg0a617e22015-10-20 15:49:38 -07002942// Test that we properly handle failures to add a receive stream.
2943TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002944 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002946 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947}
2948
solenberg0a617e22015-10-20 15:49:38 -07002949// Test that we properly handle failures to add a send stream.
2950TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002951 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002952 voe_.set_fail_create_channel(true);
2953 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2954}
2955
solenberg1ac56142015-10-13 03:58:19 -07002956// Test that AddRecvStream creates new stream.
2957TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002958 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002960 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002961 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962}
2963
2964// Test that after adding a recv stream, we do not decode more codecs than
2965// those previously passed into SetRecvCodecs.
2966TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002967 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002968 cricket::AudioRecvParameters parameters;
2969 parameters.codecs.push_back(kIsacCodec);
2970 parameters.codecs.push_back(kPcmuCodec);
2971 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002972 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002973 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2974 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2975 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002976}
2977
2978// Test that we properly clean up any streams that were added, even if
2979// not explicitly removed.
2980TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002981 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002982 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002983 EXPECT_TRUE(AddRecvStream(1));
2984 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2986 delete channel_;
2987 channel_ = NULL;
2988 EXPECT_EQ(0, voe_.GetNumChannels());
2989}
2990
wu@webrtc.org78187522013-10-07 23:32:02 +00002991TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002992 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002993 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002994}
2995
2996TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002997 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002998 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002999 // Manually delete channel to simulate a failure.
3000 int channel = voe_.GetLastChannel();
3001 EXPECT_EQ(0, voe_.DeleteChannel(channel));
3002 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07003003 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00003004 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07003005 EXPECT_NE(channel, new_channel);
3006 // The last created channel is deleted too.
3007 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00003008}
3009
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003010// Test the InsertDtmf on default send stream as caller.
3011TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08003012 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003013}
3014
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003015// Test the InsertDtmf on default send stream as callee
3016TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08003017 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003018}
3019
3020// Test the InsertDtmf on specified send stream as caller.
3021TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08003022 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003023}
3024
3025// Test the InsertDtmf on specified send stream as callee.
3026TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08003027 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028}
3029
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003030TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003031 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003032 EXPECT_CALL(adm_,
3033 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3034 EXPECT_CALL(adm_,
3035 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3036 EXPECT_CALL(adm_,
3037 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003038
solenberg246b8172015-12-08 09:50:23 -08003039 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3040 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003041
solenberg246b8172015-12-08 09:50:23 -08003042 // Nothing set in AudioOptions, so everything should be as default.
3043 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003044 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003045 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003046 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3047 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048
3049 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003050 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3051 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003052 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003053 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003054
3055 // Turn echo cancellation back on, with settings, and make sure
3056 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003057 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3058 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003059 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003060 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003061
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003062 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3063 // control.
solenberg76377c52017-02-21 00:54:31 -08003064 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3065 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003066 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003067 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003068
3069 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003070 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3071 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003072 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3073 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3074 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003075 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003076
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003077 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003078 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3079 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003080 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003081 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003082
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003084 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3085 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3086 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003088 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003089 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003090
3091 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003092 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3093 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3094 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3095 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003096 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3097 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003098 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003099
3100 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003101 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3102 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3103 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3104 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3105 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3106 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3107 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003108 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3109 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3110 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3111 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003112 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003113 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003114
solenberg1ac56142015-10-13 03:58:19 -07003115 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003116 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3117 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3118 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3119 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3120 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3121 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3122 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003123 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003124}
3125
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003126TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003127 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003128 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003129 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003130 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003131 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003132 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003133 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003134 EXPECT_CALL(adm_,
3135 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3136 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3137 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3138 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3139 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003140
kwiberg686a8ef2016-02-26 03:00:35 -08003141 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003142 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003143 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003144 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003145 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003146 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003147
3148 // Have to add a stream to make SetSend work.
3149 cricket::StreamParams stream1;
3150 stream1.ssrcs.push_back(1);
3151 channel1->AddSendStream(stream1);
3152 cricket::StreamParams stream2;
3153 stream2.ssrcs.push_back(2);
3154 channel2->AddSendStream(stream2);
3155
3156 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003157 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003158 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3159 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3160 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003161 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3162 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3163 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3164 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3165 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003166 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003167 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003168 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003169 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003170
3171 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003172 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003173 parameters_options_no_ns.options.noise_suppression =
3174 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003175 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3176 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3177 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3178 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3179 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003180 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003181 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003182 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3183 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3184 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003185 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003186
3187 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003188 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003189 parameters_options_no_agc.options.auto_gain_control =
3190 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003191 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3192 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3193 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3194 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3195 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003196 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003197 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3198 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3199 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003200 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003201
solenberg76377c52017-02-21 00:54:31 -08003202 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3203 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3204 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3205 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3206 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003207 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003208
solenberg76377c52017-02-21 00:54:31 -08003209 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3210 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3211 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3212 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3213 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003214 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003215
solenberg76377c52017-02-21 00:54:31 -08003216 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3217 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3218 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3219 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3220 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003221 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003222
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003223 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003224 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3225 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003226 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003227 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003228 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003229 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003230 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3231 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3232 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3233 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3234 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003235 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003236 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3237 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3238 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003239 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003240}
3241
wu@webrtc.orgde305012013-10-31 15:40:38 +00003242// This test verifies DSCP settings are properly applied on voice media channel.
3243TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003244 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003245 cricket::FakeNetworkInterface network_interface;
3246 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003247 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003248
solenberg059fb442016-10-26 05:12:24 -07003249 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3250 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3251
solenbergbc37fc82016-04-04 09:54:44 -07003252 channel.reset(
3253 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003254 channel->SetInterface(&network_interface);
3255 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3256 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3257
3258 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003259 channel.reset(
3260 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003261 channel->SetInterface(&network_interface);
3262 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3263
3264 // Verify that setting the option to false resets the
3265 // DiffServCodePoint.
3266 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003267 channel.reset(
3268 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003269 channel->SetInterface(&network_interface);
3270 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3271 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3272
3273 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003274}
3275
solenberg1ac56142015-10-13 03:58:19 -07003276TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003277 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003278 cricket::WebRtcVoiceMediaChannel* media_channel =
3279 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003280 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003282 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003283 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3284 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3285 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003286 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003287 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003288}
3289
solenberg1ac56142015-10-13 03:58:19 -07003290TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003291 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003292 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003293 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3294 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3295 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003296 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003297 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003298 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3299 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003300 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003301 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003302 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003303 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003304}
3305
solenberg4bac9c52015-10-09 02:32:53 -07003306TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003307 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003308 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003309 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003310 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003311 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003312 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3313 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3314 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003315}
3316
solenberg2100c0b2017-03-01 11:29:29 -08003317TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003318 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003319
3320 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003321 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003322 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3323
3324 // Should remember the volume "2" which will be set on new unsignaled streams,
3325 // and also set the gain to 2 on existing unsignaled streams.
3326 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3327 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3328
3329 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3330 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3331 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3332 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3333 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3334 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3335
3336 // Setting gain with SSRC=0 should affect all unsignaled streams.
3337 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003338 if (kMaxUnsignaledRecvStreams > 1) {
3339 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3340 }
solenberg2100c0b2017-03-01 11:29:29 -08003341 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3342
3343 // Setting gain on an individual stream affects only that.
3344 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003345 if (kMaxUnsignaledRecvStreams > 1) {
3346 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3347 }
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003349}
3350
pbos8fc7fa72015-07-15 08:02:58 -07003351TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003352 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003353 const std::string kSyncLabel = "AvSyncLabel";
3354
solenbergff976312016-03-30 23:28:51 -07003355 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003356 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3357 sp.sync_label = kSyncLabel;
3358 // Creating two channels to make sure that sync label is set properly for both
3359 // the default voice channel and following ones.
3360 EXPECT_TRUE(channel_->AddRecvStream(sp));
3361 sp.ssrcs[0] += 1;
3362 EXPECT_TRUE(channel_->AddRecvStream(sp));
3363
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003364 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003365 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003366 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003367 << "SyncGroup should be set based on sync_label";
3368 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003369 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003370 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003371}
3372
solenberg3a941542015-11-16 07:34:50 -08003373// TODO(solenberg): Remove, once recv streams are configured through Call.
3374// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003375TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003376 // Test that setting the header extensions results in the expected state
3377 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003378 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003379 ssrcs.push_back(223);
3380 ssrcs.push_back(224);
3381
solenbergff976312016-03-30 23:28:51 -07003382 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003383 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003384 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003385 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003386 cricket::StreamParams::CreateLegacy(ssrc)));
3387 }
3388
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003389 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003390 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003391 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003392 EXPECT_NE(nullptr, s);
3393 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3394 }
3395
3396 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003397 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003398 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003399 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003400 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003401 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003402 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003403 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003404 EXPECT_NE(nullptr, s);
3405 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003406 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3407 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003408 for (const auto& s_ext : s_exts) {
3409 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003410 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003411 }
3412 }
3413 }
3414 }
3415
3416 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003417 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003418 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003419 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003420 EXPECT_NE(nullptr, s);
3421 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3422 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003423}
3424
3425TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3426 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003427 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003428 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003429 static const unsigned char kRtcp[] = {
3430 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3431 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3434 };
jbaucheec21bd2016-03-20 06:15:43 -07003435 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003436
solenbergff976312016-03-30 23:28:51 -07003437 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003438 cricket::WebRtcVoiceMediaChannel* media_channel =
3439 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003440 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003441 EXPECT_TRUE(media_channel->AddRecvStream(
3442 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3443
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003444 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003445 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003446 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003447 EXPECT_EQ(0, s->received_packets());
3448 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3449 EXPECT_EQ(1, s->received_packets());
3450 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3451 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003452}
Minyue2013aec2015-05-13 14:14:42 +02003453
solenberg0a617e22015-10-20 15:49:38 -07003454// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003455// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003456TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003457 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003458 EXPECT_TRUE(AddRecvStream(kSsrcY));
3459 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003460 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003461 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3462 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3463 EXPECT_TRUE(AddRecvStream(kSsrcW));
3464 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003465}
3466
solenberg7602aab2016-11-14 11:30:07 -08003467TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3468 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003469 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003470 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003471 cricket::StreamParams::CreateLegacy(kSsrcY)));
3472 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3473 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3474 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003475 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003476 cricket::StreamParams::CreateLegacy(kSsrcW)));
3477 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3478 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003479}
stefan658910c2015-09-03 05:48:32 -07003480
deadbeef884f5852016-01-15 09:20:04 -08003481TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003482 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003483 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3484 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003485
3486 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003487 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3488 EXPECT_TRUE(AddRecvStream(kSsrcX));
3489 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003490
3491 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003492 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3493 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003494
3495 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003496 channel_->SetRawAudioSink(kSsrcX, nullptr);
3497 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003498}
3499
solenberg2100c0b2017-03-01 11:29:29 -08003500TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003501 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003502 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3503 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003504 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3505 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003506
3507 // Should be able to set a default sink even when no stream exists.
3508 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3509
solenberg2100c0b2017-03-01 11:29:29 -08003510 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3511 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003512 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003513 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003514
3515 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003516 channel_->SetRawAudioSink(kSsrc0, nullptr);
3517 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003518
3519 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003520 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3521 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003522
3523 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003524 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003525 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003526 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3527
3528 // Spawn another unsignaled stream - it should be assigned the default sink
3529 // and the previous unsignaled stream should lose it.
3530 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3531 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3532 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3533 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003534 if (kMaxUnsignaledRecvStreams > 1) {
3535 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3536 }
solenberg2100c0b2017-03-01 11:29:29 -08003537 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3538
3539 // Reset the default sink - the second unsignaled stream should lose it.
3540 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003541 if (kMaxUnsignaledRecvStreams > 1) {
3542 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3543 }
solenberg2100c0b2017-03-01 11:29:29 -08003544 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3545
3546 // Try setting the default sink while two streams exists.
3547 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003548 if (kMaxUnsignaledRecvStreams > 1) {
3549 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3550 }
solenberg2100c0b2017-03-01 11:29:29 -08003551 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3552
3553 // Try setting the sink for the first unsignaled stream using its known SSRC.
3554 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003555 if (kMaxUnsignaledRecvStreams > 1) {
3556 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3557 }
solenberg2100c0b2017-03-01 11:29:29 -08003558 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003559 if (kMaxUnsignaledRecvStreams > 1) {
3560 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3561 }
deadbeef884f5852016-01-15 09:20:04 -08003562}
3563
skvlad7a43d252016-03-22 15:32:27 -07003564// Test that, just like the video channel, the voice channel communicates the
3565// network state to the call.
3566TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003567 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003568
3569 EXPECT_EQ(webrtc::kNetworkUp,
3570 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3571 EXPECT_EQ(webrtc::kNetworkUp,
3572 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3573
3574 channel_->OnReadyToSend(false);
3575 EXPECT_EQ(webrtc::kNetworkDown,
3576 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3577 EXPECT_EQ(webrtc::kNetworkUp,
3578 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3579
3580 channel_->OnReadyToSend(true);
3581 EXPECT_EQ(webrtc::kNetworkUp,
3582 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3583 EXPECT_EQ(webrtc::kNetworkUp,
3584 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3585}
3586
aleloi18e0b672016-10-04 02:45:47 -07003587// Test that playout is still started after changing parameters
3588TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3589 SetupRecvStream();
3590 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003591 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003592
3593 // Changing RTP header extensions will recreate the AudioReceiveStream.
3594 cricket::AudioRecvParameters parameters;
3595 parameters.extensions.push_back(
3596 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3597 channel_->SetRecvParameters(parameters);
3598
solenberg2100c0b2017-03-01 11:29:29 -08003599 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003600}
3601
stefan658910c2015-09-03 05:48:32 -07003602// Tests that the library initializes and shuts down properly.
3603TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003604 // If the VoiceEngine wants to gather available codecs early, that's fine but
3605 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003606 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003607 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003608 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003609 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003610 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003611 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3612 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003613 EXPECT_TRUE(channel != nullptr);
3614 delete channel;
solenbergff976312016-03-30 23:28:51 -07003615}
stefan658910c2015-09-03 05:48:32 -07003616
solenbergff976312016-03-30 23:28:51 -07003617// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003618TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3619 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3620 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3621 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003622 // Return 100ms just in case this function gets called. If we don't,
3623 // we could enter a tight loop since the mock would return 0.
3624 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003625 {
ossuc54071d2016-08-17 02:45:41 -07003626 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003627 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003628 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003629 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003630 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003631 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3632 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3633 EXPECT_TRUE(channel != nullptr);
3634 delete channel;
3635 }
stefan658910c2015-09-03 05:48:32 -07003636}
3637
3638// Tests that the library is configured with the codecs we want.
3639TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003640 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3641 // module.
3642
stefan658910c2015-09-03 05:48:32 -07003643 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003644#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003647#endif
3648#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003649 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003650 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003651#endif
3652#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003653 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003654 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003655#endif
3656#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003657 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003658 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003659 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003660 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003661 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003662#endif
solenberg26c8c912015-11-27 04:00:25 -08003663 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003664 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003665 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003666 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003667 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003668 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003669 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3670 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3671 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3672 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3673 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3674 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003675 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003676 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003677 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003678 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003679 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003680 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003681 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003682 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003683 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003684 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003685 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003686 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003687 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003688 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003689 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003690 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003691 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003692 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003693 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003694 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003695 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003696 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003697 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003698
stefan658910c2015-09-03 05:48:32 -07003699 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003700 // TODO(ossu): Why are the payload types of codecs with non-static payload
3701 // type assignments checked here? It shouldn't really matter.
3702 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003703 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003704 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3705 if (codec.name == "CN" && codec.clockrate == 16000) {
3706 EXPECT_EQ(105, codec.id);
3707 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3708 EXPECT_EQ(106, codec.id);
3709 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3710 EXPECT_EQ(103, codec.id);
3711 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3712 EXPECT_EQ(104, codec.id);
3713 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3714 EXPECT_EQ(9, codec.id);
3715 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3716 EXPECT_EQ(126, codec.id);
3717 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3718 // Remove these checks once both send and receive side assigns payload types
3719 // dynamically.
3720 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3721 EXPECT_EQ(113, codec.id);
3722 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3723 EXPECT_EQ(112, codec.id);
3724 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3725 EXPECT_EQ(110, codec.id);
3726 } else if (codec.name == "opus") {
3727 EXPECT_EQ(111, codec.id);
3728 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3729 EXPECT_EQ("10", codec.params.find("minptime")->second);
3730 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3731 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003732 }
3733 }
stefan658910c2015-09-03 05:48:32 -07003734}
3735
3736// Tests that VoE supports at least 32 channels
3737TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003738 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003739 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003740 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003741 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003742 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003743
3744 cricket::VoiceMediaChannel* channels[32];
3745 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003746 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003747 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3748 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003749 if (!channel)
3750 break;
stefan658910c2015-09-03 05:48:32 -07003751 channels[num_channels++] = channel;
3752 }
3753
tfarina5237aaf2015-11-10 23:44:30 -08003754 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003755 EXPECT_EQ(expected, num_channels);
3756
3757 while (num_channels > 0) {
3758 delete channels[--num_channels];
3759 }
stefan658910c2015-09-03 05:48:32 -07003760}
3761
3762// Test that we set our preferred codecs properly.
3763TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003764 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3765 // - Check that our builtin codecs are usable by Channel.
3766 // - The codecs provided by the engine is usable by Channel.
3767 // It does not check that the codecs in the RecvParameters are actually
3768 // what we sent in - though it's probably reasonable to expect so, if
3769 // SetRecvParameters returns true.
3770 // I think it will become clear once audio decoder injection is completed.
3771 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003772 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003773 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003774 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003775 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003776 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3777 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003778 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003779 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003780 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003781}
ossu9def8002017-02-09 05:14:32 -08003782
3783TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3784 std::vector<webrtc::AudioCodecSpec> specs;
3785 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3786 spec1.allow_comfort_noise = false;
3787 spec1.supports_network_adaption = true;
3788 specs.push_back(spec1);
3789 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3790 spec2.allow_comfort_noise = false;
3791 specs.push_back(spec2);
3792 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3793 {{"param1", "value1b"},
3794 {"param2", "value2"}}}));
3795 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3796 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3797
3798 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3799 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3800 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3801 .WillOnce(Return(specs));
3802
3803 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3804 auto codecs = engine.recv_codecs();
3805 EXPECT_EQ(11, codecs.size());
3806
3807 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3808 // check the actual values safely, to provide better test results.
3809 auto get_codec =
3810 [&codecs](size_t index) -> const cricket::AudioCodec& {
3811 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3812 if (codecs.size() > index)
3813 return codecs[index];
3814 return missing_codec;
3815 };
3816
3817 // Ensure the general codecs are generated first and in order.
3818 for (size_t i = 0; i != specs.size(); ++i) {
3819 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3820 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3821 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3822 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3823 }
3824
3825 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003826 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003827 auto find_codec =
3828 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3829 for (size_t i = 0; i != codecs.size(); ++i) {
3830 const cricket::AudioCodec& codec = codecs[i];
3831 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3832 codec.clockrate == format.clockrate_hz &&
3833 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003834 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003835 }
3836 }
3837 return -1;
3838 };
3839
3840 // Ensure all supplementary codecs are generated last. Their internal ordering
3841 // is not important.
3842 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3843 const int num_specs = static_cast<int>(specs.size());
3844 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3845 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3846 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3847 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3848 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3849 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3850 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3851}