blob: 3777b3daa33942f93f5a45b4cab5bd1efc558f61 [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
kwiberg1724cfb2017-03-24 03:16:04 -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));
kwiberg1724cfb2017-03-24 03:16:04 -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));
kwiberg1724cfb2017-03-24 03:16:04 -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));
kwiberg1724cfb2017-03-24 03:16:04 -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));
kwiberg1724cfb2017-03-24 03:16:04 -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));
kwiberg1724cfb2017-03-24 03:16:04 -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
1175// Test that GetRtpReceiveParameters returns the currently configured codecs.
1176TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1177 EXPECT_TRUE(SetupRecvStream());
1178 cricket::AudioRecvParameters parameters;
1179 parameters.codecs.push_back(kIsacCodec);
1180 parameters.codecs.push_back(kPcmuCodec);
1181 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1182
1183 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001184 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001185 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1186 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1187 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1188}
1189
deadbeefcb443432016-12-12 11:12:36 -08001190// Test that GetRtpReceiveParameters returns an SSRC.
1191TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1192 EXPECT_TRUE(SetupRecvStream());
1193 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001194 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001195 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001196 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001197}
1198
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199// Test that if we set/get parameters multiple times, we get the same results.
1200TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1201 EXPECT_TRUE(SetupRecvStream());
1202 cricket::AudioRecvParameters parameters;
1203 parameters.codecs.push_back(kIsacCodec);
1204 parameters.codecs.push_back(kPcmuCodec);
1205 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1206
1207 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001208 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209
1210 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001211 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001212
1213 // ... And this shouldn't change the params returned by
1214 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001215 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1216 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001217}
1218
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001219// Test that we apply codecs properly.
1220TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001221 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001222 cricket::AudioSendParameters parameters;
1223 parameters.codecs.push_back(kIsacCodec);
1224 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001225 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001226 parameters.codecs[0].id = 96;
1227 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001228 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001229 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001230 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001231 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001232 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1233 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1234 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1235 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001236 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001237 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001238}
1239
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001240// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1241// to apply.
1242TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001243 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001244 cricket::AudioSendParameters parameters;
1245 parameters.codecs.push_back(kIsacCodec);
1246 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001247 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001248 parameters.codecs[0].id = 96;
1249 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001250 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001251 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001252 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001253 // Calling SetSendCodec again with same codec which is already set.
1254 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001255 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001256 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001257}
1258
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001259// Verify that G722 is set with 16000 samples per second to WebRTC.
1260TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001261 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001262 cricket::AudioSendParameters parameters;
1263 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001264 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001265 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001266 EXPECT_STREQ("G722", gcodec.plname);
1267 EXPECT_EQ(1, gcodec.channels);
1268 EXPECT_EQ(16000, gcodec.plfreq);
1269}
1270
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001271// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001272TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001273 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001274 cricket::AudioSendParameters parameters;
1275 parameters.codecs.push_back(kOpusCodec);
1276 parameters.codecs[0].bitrate = 0;
1277 parameters.codecs[0].clockrate = 50000;
1278 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001279}
1280
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001281// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001282TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001283 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001284 cricket::AudioSendParameters parameters;
1285 parameters.codecs.push_back(kOpusCodec);
1286 parameters.codecs[0].bitrate = 0;
1287 parameters.codecs[0].channels = 0;
1288 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001289}
1290
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001291// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001292TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001293 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kOpusCodec);
1296 parameters.codecs[0].bitrate = 0;
1297 parameters.codecs[0].channels = 0;
1298 parameters.codecs[0].params["stereo"] = "1";
1299 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300}
1301
1302// Test that if channel is 1 for opus and there's no stereo, we fail.
1303TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001304 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001305 cricket::AudioSendParameters parameters;
1306 parameters.codecs.push_back(kOpusCodec);
1307 parameters.codecs[0].bitrate = 0;
1308 parameters.codecs[0].channels = 1;
1309 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001310}
1311
1312// Test that if channel is 1 for opus and stereo=0, we fail.
1313TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001314 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001315 cricket::AudioSendParameters parameters;
1316 parameters.codecs.push_back(kOpusCodec);
1317 parameters.codecs[0].bitrate = 0;
1318 parameters.codecs[0].channels = 1;
1319 parameters.codecs[0].params["stereo"] = "0";
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
1323// Test that if channel is 1 for opus and stereo=1, we fail.
1324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001325 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 cricket::AudioSendParameters parameters;
1327 parameters.codecs.push_back(kOpusCodec);
1328 parameters.codecs[0].bitrate = 0;
1329 parameters.codecs[0].channels = 1;
1330 parameters.codecs[0].params["stereo"] = "1";
1331 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
1334// Test that with bitrate=0 and no stereo,
1335// channels and bitrate are 1 and 32000.
1336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
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;
solenberg059fb442016-10-26 05:12:24 -07001341 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001342 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
1345// Test that with bitrate=0 and stereo=0,
1346// channels and bitrate are 1 and 32000.
1347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
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].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001353 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001354 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001357// Test that with bitrate=invalid and stereo=0,
1358// channels and bitrate are 1 and 32000.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
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].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001364 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001365 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001366 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001367 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001368
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001370 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001371 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001372}
1373
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374// Test that with bitrate=0 and stereo=1,
1375// channels and bitrate are 2 and 64000.
1376TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001377 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 cricket::AudioSendParameters parameters;
1379 parameters.codecs.push_back(kOpusCodec);
1380 parameters.codecs[0].bitrate = 0;
1381 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001382 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001383 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384}
1385
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001386// Test that with bitrate=invalid and stereo=1,
1387// channels and bitrate are 2 and 64000.
1388TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001389 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 cricket::AudioSendParameters parameters;
1391 parameters.codecs.push_back(kOpusCodec);
1392 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001393 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001396 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001399 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001400 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001401}
1402
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403// Test that with bitrate=N and stereo unset,
1404// channels and bitrate are 1 and N.
1405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kOpusCodec);
1409 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001410 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001411 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412 EXPECT_EQ(111, gcodec.pltype);
1413 EXPECT_EQ(96000, gcodec.rate);
1414 EXPECT_STREQ("opus", gcodec.plname);
1415 EXPECT_EQ(1, gcodec.channels);
1416 EXPECT_EQ(48000, gcodec.plfreq);
1417}
1418
1419// Test that with bitrate=N and stereo=0,
1420// channels and bitrate are 1 and N.
1421TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001422 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001423 cricket::AudioSendParameters parameters;
1424 parameters.codecs.push_back(kOpusCodec);
1425 parameters.codecs[0].bitrate = 30000;
1426 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001427 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001428 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429}
1430
1431// Test that with bitrate=N and without any parameters,
1432// channels and bitrate are 1 and N.
1433TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kOpusCodec);
1437 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001439 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440}
1441
1442// Test that with bitrate=N and stereo=1,
1443// channels and bitrate are 2 and N.
1444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
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"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001451 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001454// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1455// Also test that the "maxaveragebitrate" can't be set to values outside the
1456// range of 6000 and 510000
1457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001458 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 cricket::AudioSendParameters parameters;
1460 parameters.codecs.push_back(kOpusCodec);
1461 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001462 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001464 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001465 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001466
1467 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001469 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001470 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001471
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001473 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001474 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001475}
1476
stefan13f1a0a2016-11-30 07:22:58 -08001477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1478 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1479 200000);
1480}
1481
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1483 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1484}
1485
1486TEST_F(WebRtcVoiceEngineTestFake,
1487 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1488 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1489}
1490
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1492 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake,
1496 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1497 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1498 200000);
1499 send_parameters_.max_bandwidth_bps = 300000;
1500 SetSendParameters(send_parameters_);
1501 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1502 << "Setting max bitrate should keep previous min bitrate.";
1503 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1504 << "Setting max bitrate should not reset start bitrate.";
1505 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1506}
1507
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001508// Test that we can enable NACK with opus as caller.
1509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 cricket::AudioSendParameters parameters;
1512 parameters.codecs.push_back(kOpusCodec);
1513 parameters.codecs[0].AddFeedbackParam(
1514 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1515 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001516 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001517 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001518 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001519}
1520
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001521// Test that we can enable NACK with opus as callee.
1522TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001523 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001524 cricket::AudioSendParameters parameters;
1525 parameters.codecs.push_back(kOpusCodec);
1526 parameters.codecs[0].AddFeedbackParam(
1527 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1528 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001529 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001531 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001532 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001533
1534 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001535 cricket::StreamParams::CreateLegacy(kSsrcX)));
1536 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001537}
1538
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539// Test that we can enable NACK on receive streams.
1540TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001541 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001543 cricket::AudioSendParameters parameters;
1544 parameters.codecs.push_back(kOpusCodec);
1545 parameters.codecs[0].AddFeedbackParam(
1546 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1547 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001548 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1549 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001550 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1552 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553}
1554
1555// Test that we can disable NACK.
1556TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001557 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 cricket::AudioSendParameters parameters;
1559 parameters.codecs.push_back(kOpusCodec);
1560 parameters.codecs[0].AddFeedbackParam(
1561 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1562 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 parameters.codecs.clear();
1567 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001568 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001569 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570}
1571
1572// Test that we can disable NACK on receive streams.
1573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001574 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001576 cricket::AudioSendParameters parameters;
1577 parameters.codecs.push_back(kOpusCodec);
1578 parameters.codecs[0].AddFeedbackParam(
1579 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1580 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001581 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1583 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001584
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 parameters.codecs.clear();
1586 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001587 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1589 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001590}
1591
1592// Test that NACK is enabled on a new receive stream.
1593TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001594 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001595 cricket::AudioSendParameters parameters;
1596 parameters.codecs.push_back(kIsacCodec);
1597 parameters.codecs.push_back(kCn16000Codec);
1598 parameters.codecs[0].AddFeedbackParam(
1599 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1600 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001601 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001602 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_TRUE(AddRecvStream(kSsrcY));
1605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1606 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1607 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608}
1609
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001610// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001612 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001613 cricket::AudioSendParameters parameters;
1614 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001617}
1618
1619// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001620TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001621 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001622 cricket::AudioSendParameters parameters;
1623 parameters.codecs.push_back(kOpusCodec);
1624 parameters.codecs[0].bitrate = 0;
1625 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001627 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001628}
1629
1630// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001633 cricket::AudioSendParameters parameters;
1634 parameters.codecs.push_back(kOpusCodec);
1635 parameters.codecs[0].bitrate = 0;
1636 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001638 EXPECT_TRUE(GetCodecFec(kSsrcX));
1639 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001640}
1641
1642// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
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["stereo"] = "1";
1649 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001650 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001651 EXPECT_TRUE(GetCodecFec(kSsrcX));
1652 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001653}
1654
1655// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001656TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001657 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters parameters;
1659 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001662}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001663
1664// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1665TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001666 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 cricket::AudioSendParameters parameters;
1668 parameters.codecs.push_back(kIsacCodec);
1669 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001670 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001671 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001672}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001673
1674// Test that Opus FEC status can be changed.
1675TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001676 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001677 cricket::AudioSendParameters parameters;
1678 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001679 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001681
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001682 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001684 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001685}
1686
stefanba4c0e42016-02-04 04:12:24 -08001687TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001689 cricket::AudioSendParameters send_parameters;
1690 send_parameters.codecs.push_back(kOpusCodec);
1691 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001693
1694 cricket::AudioRecvParameters recv_parameters;
1695 recv_parameters.codecs.push_back(kIsacCodec);
1696 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_TRUE(AddRecvStream(kSsrcX));
1698 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001699 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001700 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001701
ossudedfd282016-06-14 07:12:39 -07001702 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001704 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001705 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001706 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001707}
1708
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001709// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1710TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001711 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001712 cricket::AudioSendParameters parameters;
1713 parameters.codecs.push_back(kOpusCodec);
1714 parameters.codecs[0].bitrate = 0;
1715 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001717 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1718 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001719
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001721 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001722 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001723}
1724
1725// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1726TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001727 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001728 cricket::AudioSendParameters parameters;
1729 parameters.codecs.push_back(kOpusCodec);
1730 parameters.codecs[0].bitrate = 0;
1731 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001733 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1734 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001735
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001738 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001739}
1740
1741// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1742TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001743 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters parameters;
1745 parameters.codecs.push_back(kOpusCodec);
1746 parameters.codecs[0].bitrate = 0;
1747 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001749 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1750 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001751
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001752 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001753 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001754 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001755}
1756
1757// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1758TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001759 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 cricket::AudioSendParameters parameters;
1761 parameters.codecs.push_back(kOpusCodec);
1762 parameters.codecs[0].bitrate = 0;
1763 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001765 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1766 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001767
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001770 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001771}
1772
1773// Test 24000 < maxplaybackrate triggers Opus full band mode.
1774TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001775 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 cricket::AudioSendParameters parameters;
1777 parameters.codecs.push_back(kOpusCodec);
1778 parameters.codecs[0].bitrate = 0;
1779 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001781 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1782 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001783
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001785 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001786 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001787}
1788
1789// Test Opus that without maxplaybackrate, default playback rate is used.
1790TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001791 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001792 cricket::AudioSendParameters parameters;
1793 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001795 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001796}
1797
1798// Test the with non-Opus, maxplaybackrate has no effect.
1799TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001800 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001801 cricket::AudioSendParameters parameters;
1802 parameters.codecs.push_back(kIsacCodec);
1803 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001804 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001805 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001806}
1807
1808// Test maxplaybackrate can be set on two streams.
1809TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001810 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 cricket::AudioSendParameters parameters;
1812 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001813 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001814 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001815
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001818 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001819
solenberg2100c0b2017-03-01 11:29:29 -08001820 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1821 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001822}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001823
Minyue Li7100dcd2015-03-27 05:05:59 +01001824// Test that with usedtx=0, Opus DTX is off.
1825TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001826 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 cricket::AudioSendParameters parameters;
1828 parameters.codecs.push_back(kOpusCodec);
1829 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001831 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001832}
1833
1834// Test that with usedtx=1, Opus DTX is on.
1835TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
1838 parameters.codecs.push_back(kOpusCodec);
1839 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001841 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001842}
1843
1844// Test that usedtx=1 works with stereo Opus.
1845TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001846 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 cricket::AudioSendParameters parameters;
1848 parameters.codecs.push_back(kOpusCodec);
1849 parameters.codecs[0].params["usedtx"] = "1";
1850 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001852 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001853}
1854
1855// Test that usedtx=1 does not work with non Opus.
1856TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
1859 parameters.codecs.push_back(kIsacCodec);
1860 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001861 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001862 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001863}
1864
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001865// Test that we can switch back and forth between Opus and ISAC with CN.
1866TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001867 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001868
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 cricket::AudioSendParameters opus_parameters;
1870 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001871 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001872 {
solenberg2100c0b2017-03-01 11:29:29 -08001873 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001874 EXPECT_EQ(111, gcodec.pltype);
1875 EXPECT_STREQ("opus", gcodec.plname);
1876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001877
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001878 cricket::AudioSendParameters isac_parameters;
1879 isac_parameters.codecs.push_back(kIsacCodec);
1880 isac_parameters.codecs.push_back(kCn16000Codec);
1881 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001882 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001883 {
solenberg2100c0b2017-03-01 11:29:29 -08001884 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001885 EXPECT_EQ(103, gcodec.pltype);
1886 EXPECT_STREQ("ISAC", gcodec.plname);
1887 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001888
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001890 {
solenberg2100c0b2017-03-01 11:29:29 -08001891 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001892 EXPECT_EQ(111, gcodec.pltype);
1893 EXPECT_STREQ("opus", gcodec.plname);
1894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001895}
1896
1897// Test that we handle various ways of specifying bitrate.
1898TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001899 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 cricket::AudioSendParameters parameters;
1901 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001902 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001903 {
solenberg2100c0b2017-03-01 11:29:29 -08001904 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(103, gcodec.pltype);
1906 EXPECT_STREQ("ISAC", gcodec.plname);
1907 EXPECT_EQ(32000, gcodec.rate);
1908 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001909
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001910 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001912 {
solenberg2100c0b2017-03-01 11:29:29 -08001913 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001914 EXPECT_EQ(103, gcodec.pltype);
1915 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001916 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001917 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001919 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001920 {
solenberg2100c0b2017-03-01 11:29:29 -08001921 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001922 EXPECT_EQ(103, gcodec.pltype);
1923 EXPECT_STREQ("ISAC", gcodec.plname);
1924 EXPECT_EQ(28000, gcodec.rate);
1925 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001926
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001927 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001928 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001929 {
solenberg2100c0b2017-03-01 11:29:29 -08001930 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001931 EXPECT_EQ(0, gcodec.pltype);
1932 EXPECT_STREQ("PCMU", gcodec.plname);
1933 EXPECT_EQ(64000, gcodec.rate);
1934 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001936 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001937 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001938 {
solenberg2100c0b2017-03-01 11:29:29 -08001939 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001940 EXPECT_EQ(0, gcodec.pltype);
1941 EXPECT_STREQ("PCMU", gcodec.plname);
1942 EXPECT_EQ(64000, gcodec.rate);
1943 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001945 parameters.codecs[0] = kOpusCodec;
1946 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001948 {
solenberg2100c0b2017-03-01 11:29:29 -08001949 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001950 EXPECT_EQ(111, gcodec.pltype);
1951 EXPECT_STREQ("opus", gcodec.plname);
1952 EXPECT_EQ(32000, gcodec.rate);
1953 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001954}
1955
Brave Yao5225dd82015-03-26 07:39:19 +08001956// Test that we could set packet size specified in kCodecParamPTime.
1957TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001958 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 cricket::AudioSendParameters parameters;
1960 parameters.codecs.push_back(kOpusCodec);
1961 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001962 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001963 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001964
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001965 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001966 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001967 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001968
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001971 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001972
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001973 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1974 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001975 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001976 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001977 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001978
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001979 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1980 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001983 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001984}
1985
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001986// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001987TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001988 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001989 cricket::AudioSendParameters parameters;
1990 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001991}
1992
1993// Test that we can set send codecs even with telephone-event codec as the first
1994// one on the list.
1995TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001996 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001998 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs.push_back(kIsacCodec);
2000 parameters.codecs.push_back(kPcmuCodec);
2001 parameters.codecs[0].id = 98; // DTMF
2002 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002003 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002004 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002005 EXPECT_EQ(96, gcodec.pltype);
2006 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002007 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002008}
2009
solenberg31642aa2016-03-14 08:00:37 -07002010// Test that payload type range is limited for telephone-event codec.
2011TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002012 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002013 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002014 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002015 parameters.codecs.push_back(kIsacCodec);
2016 parameters.codecs[0].id = 0; // DTMF
2017 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002018 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002019 EXPECT_TRUE(channel_->CanInsertDtmf());
2020 parameters.codecs[0].id = 128; // DTMF
2021 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2022 EXPECT_FALSE(channel_->CanInsertDtmf());
2023 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002024 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002025 EXPECT_TRUE(channel_->CanInsertDtmf());
2026 parameters.codecs[0].id = -1; // DTMF
2027 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2028 EXPECT_FALSE(channel_->CanInsertDtmf());
2029}
2030
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002031// Test that we can set send codecs even with CN codec as the first
2032// one on the list.
2033TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002034 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002035 cricket::AudioSendParameters parameters;
2036 parameters.codecs.push_back(kCn16000Codec);
2037 parameters.codecs.push_back(kIsacCodec);
2038 parameters.codecs.push_back(kPcmuCodec);
2039 parameters.codecs[0].id = 98; // wideband CN
2040 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002041 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002042 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002043 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2044 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2045 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2046 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002047}
2048
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002049// Test that we set VAD and DTMF types correctly as caller.
2050TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002051 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002052 cricket::AudioSendParameters parameters;
2053 parameters.codecs.push_back(kIsacCodec);
2054 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002055 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002056 parameters.codecs.push_back(kCn16000Codec);
2057 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002058 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002059 parameters.codecs[0].id = 96;
2060 parameters.codecs[2].id = 97; // wideband CN
2061 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002063 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002064 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2065 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2066 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2067 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2068 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2069 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002070 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002071}
2072
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002073// Test that we set VAD and DTMF types correctly as callee.
2074TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002075 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002076 cricket::AudioSendParameters parameters;
2077 parameters.codecs.push_back(kIsacCodec);
2078 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002079 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002080 parameters.codecs.push_back(kCn16000Codec);
2081 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002082 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002083 parameters.codecs[0].id = 96;
2084 parameters.codecs[2].id = 97; // wideband CN
2085 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002086 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002087 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002088 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002089
solenberg2100c0b2017-03-01 11:29:29 -08002090 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002091 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2092 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2093 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2094 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2095 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2096 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002097 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002098}
2099
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100// Test that we only apply VAD if we have a CN codec that matches the
2101// send codec clockrate.
2102TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002103 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002104 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002105 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002106 parameters.codecs.push_back(kIsacCodec);
2107 parameters.codecs.push_back(kCn16000Codec);
2108 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002109 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002110 {
solenberg2100c0b2017-03-01 11:29:29 -08002111 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002112 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2113 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2114 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2115 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2116 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2117 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002119 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002121 {
solenberg2100c0b2017-03-01 11:29:29 -08002122 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002123 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2124 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2125 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002126 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002127 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002128 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002129 {
solenberg2100c0b2017-03-01 11:29:29 -08002130 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002131 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2132 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2133 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2134 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2135 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2136 }
Brave Yao5225dd82015-03-26 07:39:19 +08002137 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002138 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002139 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002140 {
solenberg2100c0b2017-03-01 11:29:29 -08002141 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002142 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2143 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2144 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145}
2146
2147// Test that we perform case-insensitive matching of codec names.
2148TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002149 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002150 cricket::AudioSendParameters parameters;
2151 parameters.codecs.push_back(kIsacCodec);
2152 parameters.codecs.push_back(kPcmuCodec);
2153 parameters.codecs.push_back(kCn16000Codec);
2154 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002155 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002156 parameters.codecs[0].name = "iSaC";
2157 parameters.codecs[0].id = 96;
2158 parameters.codecs[2].id = 97; // wideband CN
2159 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002160 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002161 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002162 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2163 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2164 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2165 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2166 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2167 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002168 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169}
2170
stefanba4c0e42016-02-04 04:12:24 -08002171class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2172 public:
2173 WebRtcVoiceEngineWithSendSideBweTest()
2174 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2175};
2176
2177TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2178 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002179 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002180 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002181 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2182 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2183 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002184 extension.id);
2185 return;
2186 }
2187 }
2188 FAIL() << "Transport sequence number extension not in header-extension list.";
2189}
2190
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002191// Test support for audio level header extension.
2192TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002193 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002194}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002195TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002196 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002197}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002198
solenbergd4adce42016-11-17 06:26:52 -08002199// Test support for transport sequence number header extension.
2200TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2201 TestSetSendRtpHeaderExtensions(
2202 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002203}
solenbergd4adce42016-11-17 06:26:52 -08002204TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2205 TestSetRecvRtpHeaderExtensions(
2206 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002207}
2208
solenberg1ac56142015-10-13 03:58:19 -07002209// Test that we can create a channel and start sending on it.
2210TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002211 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002212 SetSendParameters(send_parameters_);
2213 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002215 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002217}
2218
2219// Test that a channel will send if and only if it has a source and is enabled
2220// for sending.
2221TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002222 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002223 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002224 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002225 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002226 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2227 SetAudioSend(kSsrcX, true, &fake_source_);
2228 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2229 SetAudioSend(kSsrcX, true, nullptr);
2230 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002231}
2232
solenberg94218532016-06-16 10:53:22 -07002233// Test that a channel is muted/unmuted.
2234TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2235 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002236 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2238 SetAudioSend(kSsrcX, true, nullptr);
2239 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2240 SetAudioSend(kSsrcX, false, nullptr);
2241 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002242}
2243
solenberg6d6e7c52016-04-13 09:07:30 -07002244// Test that SetSendParameters() does not alter a stream's send state.
2245TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2246 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002247 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002248
2249 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002250 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002251 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002252
2253 // Changing RTP header extensions will recreate the AudioSendStream.
2254 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002255 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002256 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002257 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002258
2259 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002260 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002261 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002262
2263 // Changing RTP header extensions will recreate the AudioSendStream.
2264 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002265 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002266 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002267}
2268
solenberg1ac56142015-10-13 03:58:19 -07002269// Test that we can create a channel and start playing out on it.
2270TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002271 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002272 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002273 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002274 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002275 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002276 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002277}
2278
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002279// Test that we can add and remove send streams.
2280TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2281 SetupForMultiSendStream();
2282
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002283 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002284 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002285
solenbergc96df772015-10-21 13:01:53 -07002286 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002287 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002288 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002289 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002290 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002291 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002292 }
tfarina5237aaf2015-11-10 23:44:30 -08002293 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002294
solenbergc96df772015-10-21 13:01:53 -07002295 // Delete the send streams.
2296 for (uint32_t ssrc : kSsrcs4) {
2297 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002298 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002299 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002300 }
solenbergc96df772015-10-21 13:01:53 -07002301 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002302}
2303
2304// Test SetSendCodecs correctly configure the codecs in all send streams.
2305TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2306 SetupForMultiSendStream();
2307
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002308 // Create send streams.
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)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002312 }
2313
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002314 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002315 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002316 parameters.codecs.push_back(kIsacCodec);
2317 parameters.codecs.push_back(kCn16000Codec);
2318 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002319 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002320
2321 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002322 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002323 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2324 const auto& send_codec_spec =
2325 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2326 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2327 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2328 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2329 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2330 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002331 }
2332
minyue7a973442016-10-20 03:27:12 -07002333 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002334 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002335 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002336 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002337 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2338 const auto& send_codec_spec =
2339 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2340 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002341 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342 }
2343}
2344
2345// Test we can SetSend on all send streams correctly.
2346TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2347 SetupForMultiSendStream();
2348
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002349 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002350 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002351 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002352 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002353 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002354 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 }
2356
2357 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002358 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002359 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002360 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002361 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002362 }
2363
2364 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002365 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002366 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002367 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002368 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002369 }
2370}
2371
2372// Test we can set the correct statistics on all send streams.
2373TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2374 SetupForMultiSendStream();
2375
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002376 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002377 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002378 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002379 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002380 }
solenberg85a04962015-10-27 03:35:21 -07002381
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002382 // Create a receive stream to check that none of the send streams end up in
2383 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002384 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002385
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002386 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002387 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002388 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002389 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002390
solenberg85a04962015-10-27 03:35:21 -07002391 // Check stats for the added streams.
2392 {
2393 cricket::VoiceMediaInfo info;
2394 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002395
solenberg85a04962015-10-27 03:35:21 -07002396 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002397 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002398 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002399 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002400 }
hbos1acfbd22016-11-17 23:43:29 -08002401 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002402
2403 // We have added one receive stream. We should see empty stats.
2404 EXPECT_EQ(info.receivers.size(), 1u);
2405 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002406 }
solenberg1ac56142015-10-13 03:58:19 -07002407
solenberg2100c0b2017-03-01 11:29:29 -08002408 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002409 {
2410 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002411 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002412 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002413 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002414 EXPECT_EQ(0u, info.receivers.size());
2415 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002416
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002417 // Deliver a new packet - a default receive stream should be created and we
2418 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002419 {
2420 cricket::VoiceMediaInfo info;
2421 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2422 SetAudioReceiveStreamStats();
2423 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002424 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002425 EXPECT_EQ(1u, info.receivers.size());
2426 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002427 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002428 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002429}
2430
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002431// Test that we can add and remove receive streams, and do proper send/playout.
2432// We can receive on multiple streams while sending one stream.
2433TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002434 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435
solenberg1ac56142015-10-13 03:58:19 -07002436 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002437 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002438 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439
solenberg1ac56142015-10-13 03:58:19 -07002440 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002441 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002442 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002443 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444
solenberg1ac56142015-10-13 03:58:19 -07002445 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002446 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447
2448 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002449 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2450 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2451 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452
2453 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002454 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002455 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002456
2457 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002458 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002459 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2460 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461
aleloi84ef6152016-08-04 05:28:21 -07002462 // Restart playout and make sure recv streams are played out.
2463 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2465 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466
aleloi84ef6152016-08-04 05:28:21 -07002467 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002468 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2469 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470}
2471
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002473// and start sending on it.
2474TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002475 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002476 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2477 EXPECT_CALL(apm_gc_,
2478 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002479 SetSendParameters(send_parameters_);
2480 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002482 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484}
2485
wu@webrtc.org97077a32013-10-25 21:18:33 +00002486TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002488 EXPECT_CALL(adm_,
2489 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002490 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2491 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002492 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2493 send_parameters_.options.tx_agc_digital_compression_gain =
2494 rtc::Optional<uint16_t>(9);
2495 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2496 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002497 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2498 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2499 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002500 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002501
2502 // Check interaction with adjust_agc_delta. Both should be respected, for
2503 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002504 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002505 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002506 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002507}
2508
wu@webrtc.org97077a32013-10-25 21:18:33 +00002509TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002510 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002511 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2512 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002513 send_parameters_.options.recording_sample_rate =
2514 rtc::Optional<uint32_t>(48000);
2515 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002516 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002517}
2518
minyue6b825df2016-10-31 04:08:32 -07002519TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2520 EXPECT_TRUE(SetupSendStream());
2521 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2522 send_parameters_.options.audio_network_adaptor_config =
2523 rtc::Optional<std::string>("1234");
2524 SetSendParameters(send_parameters_);
2525 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002526 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002527}
2528
2529TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2530 EXPECT_TRUE(SetupSendStream());
2531 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2532 send_parameters_.options.audio_network_adaptor_config =
2533 rtc::Optional<std::string>("1234");
2534 SetSendParameters(send_parameters_);
2535 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002536 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002537 const int initial_num = call_.GetNumCreatedSendStreams();
2538 cricket::AudioOptions options;
2539 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002540 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002541 // AudioSendStream expected to be recreated.
2542 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002543 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002544}
2545
2546TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2547 EXPECT_TRUE(SetupSendStream());
2548 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2549 send_parameters_.options.audio_network_adaptor_config =
2550 rtc::Optional<std::string>("1234");
2551 SetSendParameters(send_parameters_);
2552 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002553 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002554 const int initial_num = call_.GetNumCreatedSendStreams();
2555 cricket::AudioOptions options;
2556 options.audio_network_adaptor = rtc::Optional<bool>();
2557 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2558 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002559 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002560 // AudioSendStream not expected to be recreated.
2561 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2562 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002563 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002564}
2565
michaelt6672b262017-01-11 10:17:59 -08002566class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2567 : public WebRtcVoiceEngineTestFake {
2568 public:
2569 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2570 : WebRtcVoiceEngineTestFake(
2571 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2572 "Enabled/") {}
2573};
2574
2575TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2576 EXPECT_TRUE(SetupSendStream());
2577 cricket::AudioSendParameters parameters;
2578 parameters.codecs.push_back(kOpusCodec);
2579 SetSendParameters(parameters);
2580 const int initial_num = call_.GetNumCreatedSendStreams();
2581 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2582
2583 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2584 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002585 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2586 constexpr int kMinOverheadBps =
2587 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002588 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2589
2590 constexpr int kOpusMinBitrateBps = 6000;
2591 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002592 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002593 constexpr int kOpusBitrateFbBps = 32000;
2594 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002595 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002596
2597 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2598 parameters.options.audio_network_adaptor_config =
2599 rtc::Optional<std::string>("1234");
2600 SetSendParameters(parameters);
2601
ossu11bfc532017-02-16 05:37:06 -08002602 constexpr int kMinOverheadWithAnaBps =
2603 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002604 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2605
2606 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002607 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002608
2609 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002610 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002611}
2612
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002614// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002615TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002616 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002617 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002618}
2619
2620TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2621 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002622 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002623 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002624 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002625 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002626 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002627 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002628 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629
solenberg85a04962015-10-27 03:35:21 -07002630 // Check stats for the added streams.
2631 {
2632 cricket::VoiceMediaInfo info;
2633 EXPECT_EQ(true, channel_->GetStats(&info));
2634
2635 // We have added one send stream. We should see the stats we've set.
2636 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002637 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002638 // We have added one receive stream. We should see empty stats.
2639 EXPECT_EQ(info.receivers.size(), 1u);
2640 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2641 }
solenberg1ac56142015-10-13 03:58:19 -07002642
solenberg566ef242015-11-06 15:34:49 -08002643 // Start sending - this affects some reported stats.
2644 {
2645 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002646 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002647 EXPECT_EQ(true, channel_->GetStats(&info));
2648 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002649 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002650 }
2651
solenberg2100c0b2017-03-01 11:29:29 -08002652 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002653 {
2654 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002655 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002656 EXPECT_EQ(true, channel_->GetStats(&info));
2657 EXPECT_EQ(1u, info.senders.size());
2658 EXPECT_EQ(0u, info.receivers.size());
2659 }
solenberg1ac56142015-10-13 03:58:19 -07002660
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002661 // Deliver a new packet - a default receive stream should be created and we
2662 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002663 {
2664 cricket::VoiceMediaInfo info;
2665 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2666 SetAudioReceiveStreamStats();
2667 EXPECT_EQ(true, channel_->GetStats(&info));
2668 EXPECT_EQ(1u, info.senders.size());
2669 EXPECT_EQ(1u, info.receivers.size());
2670 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002671 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002672 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002673}
2674
2675// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002676// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002677TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002678 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002679 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2680 EXPECT_TRUE(AddRecvStream(kSsrcY));
2681 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002682}
2683
2684// Test that the local SSRC is the same on sending and receiving channels if the
2685// receive channel is created before the send channel.
2686TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002687 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002688 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002689 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002690 cricket::StreamParams::CreateLegacy(kSsrcX)));
2691 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2692 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693}
2694
2695// Test that we can properly receive packets.
2696TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002697 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002698 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002700
2701 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2702 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703}
2704
2705// Test that we can properly receive packets on multiple streams.
2706TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002707 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002708 const uint32_t ssrc1 = 1;
2709 const uint32_t ssrc2 = 2;
2710 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002711 EXPECT_TRUE(AddRecvStream(ssrc1));
2712 EXPECT_TRUE(AddRecvStream(ssrc2));
2713 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002715 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002716 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002718 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719 }
mflodman3d7db262016-04-29 00:57:13 -07002720
2721 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2722 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2723 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2724
2725 EXPECT_EQ(s1.received_packets(), 0);
2726 EXPECT_EQ(s2.received_packets(), 0);
2727 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002728
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002730 EXPECT_EQ(s1.received_packets(), 0);
2731 EXPECT_EQ(s2.received_packets(), 0);
2732 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002733
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002735 EXPECT_EQ(s1.received_packets(), 1);
2736 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2737 EXPECT_EQ(s2.received_packets(), 0);
2738 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002739
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002741 EXPECT_EQ(s1.received_packets(), 1);
2742 EXPECT_EQ(s2.received_packets(), 1);
2743 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2744 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002745
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002747 EXPECT_EQ(s1.received_packets(), 1);
2748 EXPECT_EQ(s2.received_packets(), 1);
2749 EXPECT_EQ(s3.received_packets(), 1);
2750 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002751
mflodman3d7db262016-04-29 00:57:13 -07002752 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2753 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2754 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755}
2756
solenberg2100c0b2017-03-01 11:29:29 -08002757// Test that receiving on an unsignaled stream works (a stream is created).
2758TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002760 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2761
solenberg7e63ef02015-11-20 00:19:43 -08002762 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002763
2764 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002765 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2766 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002767}
2768
solenberg2100c0b2017-03-01 11:29:29 -08002769// Test that receiving N unsignaled stream works (streams will be created), and
2770// that packets are forwarded to them all.
2771TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002773 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002774 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2775
solenberg2100c0b2017-03-01 11:29:29 -08002776 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002777 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002778 rtc::SetBE32(&packet[8], ssrc);
2779 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002780
solenberg2100c0b2017-03-01 11:29:29 -08002781 // Verify we have one new stream for each loop iteration.
2782 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002783 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2784 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002785 }
mflodman3d7db262016-04-29 00:57:13 -07002786
solenberg2100c0b2017-03-01 11:29:29 -08002787 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002788 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002789 rtc::SetBE32(&packet[8], ssrc);
2790 DeliverPacket(packet, sizeof(packet));
2791
solenbergebb349d2017-03-13 05:46:15 -07002792 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002793 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2794 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2795 }
2796
2797 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2798 constexpr uint32_t kAnotherSsrc = 667;
2799 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002800 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002801
2802 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002803 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002804 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002805 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002806 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2807 EXPECT_EQ(2, streams[i]->received_packets());
2808 }
2809 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2810 EXPECT_EQ(1, streams[i]->received_packets());
2811 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002812 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002813}
2814
solenberg2100c0b2017-03-01 11:29:29 -08002815// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002816// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002817TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002818 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002819 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002820 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2821
2822 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002823 const uint32_t signaled_ssrc = 1;
2824 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002825 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002826 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002827 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2828 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002829 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002830
2831 // Note that the first unknown SSRC cannot be 0, because we only support
2832 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002833 const uint32_t unsignaled_ssrc = 7011;
2834 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002835 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002836 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2837 packet, sizeof(packet)));
2838 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2839
2840 DeliverPacket(packet, sizeof(packet));
2841 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2842
2843 rtc::SetBE32(&packet[8], signaled_ssrc);
2844 DeliverPacket(packet, sizeof(packet));
2845 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2846 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002847}
2848
solenberg4904fb62017-02-17 12:01:14 -08002849// Two tests to verify that adding a receive stream with the same SSRC as a
2850// previously added unsignaled stream will only recreate underlying stream
2851// objects if the stream parameters have changed.
2852TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2853 EXPECT_TRUE(SetupChannel());
2854
2855 // Spawn unsignaled stream with SSRC=1.
2856 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2857 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2858 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2859 sizeof(kPcmuFrame)));
2860
2861 // Verify that the underlying stream object in Call is not recreated when a
2862 // stream with SSRC=1 is added.
2863 const auto& streams = call_.GetAudioReceiveStreams();
2864 EXPECT_EQ(1, streams.size());
2865 int audio_receive_stream_id = streams.front()->id();
2866 EXPECT_TRUE(AddRecvStream(1));
2867 EXPECT_EQ(1, streams.size());
2868 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2869}
2870
2871TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2872 EXPECT_TRUE(SetupChannel());
2873
2874 // Spawn unsignaled stream with SSRC=1.
2875 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2876 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2877 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2878 sizeof(kPcmuFrame)));
2879
2880 // Verify that the underlying stream object in Call *is* recreated when a
2881 // stream with SSRC=1 is added, and which has changed stream parameters.
2882 const auto& streams = call_.GetAudioReceiveStreams();
2883 EXPECT_EQ(1, streams.size());
2884 int audio_receive_stream_id = streams.front()->id();
2885 cricket::StreamParams stream_params;
2886 stream_params.ssrcs.push_back(1);
2887 stream_params.sync_label = "sync_label";
2888 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2889 EXPECT_EQ(1, streams.size());
2890 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2891}
2892
solenberg0a617e22015-10-20 15:49:38 -07002893// Test that we properly handle failures to add a receive stream.
2894TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002895 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002897 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898}
2899
solenberg0a617e22015-10-20 15:49:38 -07002900// Test that we properly handle failures to add a send stream.
2901TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002902 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002903 voe_.set_fail_create_channel(true);
2904 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2905}
2906
solenberg1ac56142015-10-13 03:58:19 -07002907// Test that AddRecvStream creates new stream.
2908TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002909 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002911 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002912 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913}
2914
2915// Test that after adding a recv stream, we do not decode more codecs than
2916// those previously passed into SetRecvCodecs.
2917TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002918 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002919 cricket::AudioRecvParameters parameters;
2920 parameters.codecs.push_back(kIsacCodec);
2921 parameters.codecs.push_back(kPcmuCodec);
2922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002923 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1724cfb2017-03-24 03:16:04 -07002924 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2925 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2926 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927}
2928
2929// Test that we properly clean up any streams that were added, even if
2930// not explicitly removed.
2931TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002932 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002933 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002934 EXPECT_TRUE(AddRecvStream(1));
2935 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2937 delete channel_;
2938 channel_ = NULL;
2939 EXPECT_EQ(0, voe_.GetNumChannels());
2940}
2941
wu@webrtc.org78187522013-10-07 23:32:02 +00002942TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002943 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002944 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002945}
2946
2947TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002948 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002949 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002950 // Manually delete channel to simulate a failure.
2951 int channel = voe_.GetLastChannel();
2952 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2953 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002954 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002955 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002956 EXPECT_NE(channel, new_channel);
2957 // The last created channel is deleted too.
2958 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002959}
2960
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002961// Test the InsertDtmf on default send stream as caller.
2962TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002963 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002964}
2965
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002966// Test the InsertDtmf on default send stream as callee
2967TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002968 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002969}
2970
2971// Test the InsertDtmf on specified send stream as caller.
2972TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002973 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002974}
2975
2976// Test the InsertDtmf on specified send stream as callee.
2977TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002978 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979}
2980
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002982 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002983 EXPECT_CALL(adm_,
2984 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2985 EXPECT_CALL(adm_,
2986 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2987 EXPECT_CALL(adm_,
2988 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002989
solenberg246b8172015-12-08 09:50:23 -08002990 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2991 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
solenberg246b8172015-12-08 09:50:23 -08002993 // Nothing set in AudioOptions, so everything should be as default.
2994 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002995 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002996 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002997 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2998 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
3000 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3002 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003003 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003004 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005
3006 // Turn echo cancellation back on, with settings, and make sure
3007 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003008 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3009 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003010 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003011 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003013 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3014 // control.
solenberg76377c52017-02-21 00:54:31 -08003015 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3016 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003017 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003018 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003019
3020 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003021 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3022 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003023 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3024 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3025 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003026 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003027
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003028 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003029 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3030 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003031 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003032 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003033
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003035 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3036 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3037 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3038 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003039 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003040 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003041
3042 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003043 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3044 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3045 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3046 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003047 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3048 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003049 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050
3051 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003052 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3053 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3054 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3055 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3056 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3057 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3058 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003059 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3060 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3061 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3062 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003063 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003064 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003065
solenberg1ac56142015-10-13 03:58:19 -07003066 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003067 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3068 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3069 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3070 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3071 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3072 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3073 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003074 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075}
3076
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003078 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003079 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003080 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003081 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003082 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003083 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003084 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003085 EXPECT_CALL(adm_,
3086 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3087 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3088 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3089 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3090 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003091
kwiberg686a8ef2016-02-26 03:00:35 -08003092 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003093 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003094 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003095 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003096 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003097 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003098
3099 // Have to add a stream to make SetSend work.
3100 cricket::StreamParams stream1;
3101 stream1.ssrcs.push_back(1);
3102 channel1->AddSendStream(stream1);
3103 cricket::StreamParams stream2;
3104 stream2.ssrcs.push_back(2);
3105 channel2->AddSendStream(stream2);
3106
3107 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003108 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003109 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3110 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3111 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003112 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3113 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3114 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3115 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3116 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003117 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003118 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003119 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003120 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003121
3122 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003123 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003124 parameters_options_no_ns.options.noise_suppression =
3125 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003126 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3127 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3128 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3129 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3130 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003131 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003132 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003133 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3134 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3135 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003136 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003137
3138 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003140 parameters_options_no_agc.options.auto_gain_control =
3141 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003142 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3143 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3144 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3145 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3146 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003147 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003148 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3149 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3150 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003151 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003152
solenberg76377c52017-02-21 00:54:31 -08003153 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3154 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3155 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3156 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3157 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003158 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003159
solenberg76377c52017-02-21 00:54:31 -08003160 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3161 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3162 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3163 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3164 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003165 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003166
solenberg76377c52017-02-21 00:54:31 -08003167 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3168 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3169 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3170 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3171 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003172 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003173
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003174 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003175 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3176 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003177 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003178 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003179 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003180 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003181 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3182 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3183 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3184 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3185 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003186 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003187 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3188 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3189 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003190 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003191}
3192
wu@webrtc.orgde305012013-10-31 15:40:38 +00003193// This test verifies DSCP settings are properly applied on voice media channel.
3194TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003195 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003196 cricket::FakeNetworkInterface network_interface;
3197 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003198 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003199
solenberg059fb442016-10-26 05:12:24 -07003200 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3201 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3202
solenbergbc37fc82016-04-04 09:54:44 -07003203 channel.reset(
3204 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003205 channel->SetInterface(&network_interface);
3206 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3207 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3208
3209 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003210 channel.reset(
3211 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003212 channel->SetInterface(&network_interface);
3213 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3214
3215 // Verify that setting the option to false resets the
3216 // DiffServCodePoint.
3217 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003218 channel.reset(
3219 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003220 channel->SetInterface(&network_interface);
3221 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3222 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3223
3224 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003225}
3226
solenberg1ac56142015-10-13 03:58:19 -07003227TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003228 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003229 cricket::WebRtcVoiceMediaChannel* media_channel =
3230 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003231 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003232 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003233 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003234 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3235 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3236 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003237 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003239}
3240
solenberg1ac56142015-10-13 03:58:19 -07003241TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003242 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003243 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003244 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3245 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3246 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003247 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003248 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003249 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3250 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003251 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003252 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003253 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003254 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255}
3256
solenberg4bac9c52015-10-09 02:32:53 -07003257TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003258 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003260 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003261 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003262 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003263 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3264 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3265 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003266}
3267
solenberg2100c0b2017-03-01 11:29:29 -08003268TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003269 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003270
3271 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003272 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3274
3275 // Should remember the volume "2" which will be set on new unsignaled streams,
3276 // and also set the gain to 2 on existing unsignaled streams.
3277 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3278 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3279
3280 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3281 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3282 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3283 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3284 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3285 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3286
3287 // Setting gain with SSRC=0 should affect all unsignaled streams.
3288 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003289 if (kMaxUnsignaledRecvStreams > 1) {
3290 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3291 }
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3293
3294 // Setting gain on an individual stream affects only that.
3295 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003296 if (kMaxUnsignaledRecvStreams > 1) {
3297 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3298 }
solenberg2100c0b2017-03-01 11:29:29 -08003299 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003300}
3301
pbos8fc7fa72015-07-15 08:02:58 -07003302TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003303 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003304 const std::string kSyncLabel = "AvSyncLabel";
3305
solenbergff976312016-03-30 23:28:51 -07003306 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003307 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3308 sp.sync_label = kSyncLabel;
3309 // Creating two channels to make sure that sync label is set properly for both
3310 // the default voice channel and following ones.
3311 EXPECT_TRUE(channel_->AddRecvStream(sp));
3312 sp.ssrcs[0] += 1;
3313 EXPECT_TRUE(channel_->AddRecvStream(sp));
3314
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003315 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003316 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003317 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003318 << "SyncGroup should be set based on sync_label";
3319 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003320 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003321 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003322}
3323
solenberg3a941542015-11-16 07:34:50 -08003324// TODO(solenberg): Remove, once recv streams are configured through Call.
3325// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003326TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003327 // Test that setting the header extensions results in the expected state
3328 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003329 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003330 ssrcs.push_back(223);
3331 ssrcs.push_back(224);
3332
solenbergff976312016-03-30 23:28:51 -07003333 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003334 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003335 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003336 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003337 cricket::StreamParams::CreateLegacy(ssrc)));
3338 }
3339
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003340 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003341 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003342 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343 EXPECT_NE(nullptr, s);
3344 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3345 }
3346
3347 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003348 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003349 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003350 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003351 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003352 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003353 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003354 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003355 EXPECT_NE(nullptr, s);
3356 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003357 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3358 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003359 for (const auto& s_ext : s_exts) {
3360 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003361 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003362 }
3363 }
3364 }
3365 }
3366
3367 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003368 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003369 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003370 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 EXPECT_NE(nullptr, s);
3372 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3373 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003374}
3375
3376TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3377 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003378 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003379 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003380 static const unsigned char kRtcp[] = {
3381 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3382 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3385 };
jbaucheec21bd2016-03-20 06:15:43 -07003386 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003387
solenbergff976312016-03-30 23:28:51 -07003388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003389 cricket::WebRtcVoiceMediaChannel* media_channel =
3390 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003391 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003392 EXPECT_TRUE(media_channel->AddRecvStream(
3393 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3394
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003395 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003396 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003397 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003398 EXPECT_EQ(0, s->received_packets());
3399 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3400 EXPECT_EQ(1, s->received_packets());
3401 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3402 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003403}
Minyue2013aec2015-05-13 14:14:42 +02003404
solenberg0a617e22015-10-20 15:49:38 -07003405// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003406// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003407TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003408 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003409 EXPECT_TRUE(AddRecvStream(kSsrcY));
3410 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003411 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003412 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3413 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3414 EXPECT_TRUE(AddRecvStream(kSsrcW));
3415 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003416}
3417
solenberg7602aab2016-11-14 11:30:07 -08003418TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3419 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003420 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003421 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003422 cricket::StreamParams::CreateLegacy(kSsrcY)));
3423 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3424 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3425 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003426 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003427 cricket::StreamParams::CreateLegacy(kSsrcW)));
3428 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3429 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003430}
stefan658910c2015-09-03 05:48:32 -07003431
deadbeef884f5852016-01-15 09:20:04 -08003432TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003433 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003434 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3435 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003436
3437 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003438 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3439 EXPECT_TRUE(AddRecvStream(kSsrcX));
3440 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003441
3442 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003443 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3444 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003445
3446 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003447 channel_->SetRawAudioSink(kSsrcX, nullptr);
3448 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003449}
3450
solenberg2100c0b2017-03-01 11:29:29 -08003451TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003452 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003453 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3454 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003455 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3456 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003457
3458 // Should be able to set a default sink even when no stream exists.
3459 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3460
solenberg2100c0b2017-03-01 11:29:29 -08003461 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3462 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003463 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003464 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003465
3466 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003467 channel_->SetRawAudioSink(kSsrc0, nullptr);
3468 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003469
3470 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003471 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3472 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003473
3474 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003475 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003476 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003477 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3478
3479 // Spawn another unsignaled stream - it should be assigned the default sink
3480 // and the previous unsignaled stream should lose it.
3481 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3482 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3483 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3484 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003485 if (kMaxUnsignaledRecvStreams > 1) {
3486 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3487 }
solenberg2100c0b2017-03-01 11:29:29 -08003488 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3489
3490 // Reset the default sink - the second unsignaled stream should lose it.
3491 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003492 if (kMaxUnsignaledRecvStreams > 1) {
3493 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3494 }
solenberg2100c0b2017-03-01 11:29:29 -08003495 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3496
3497 // Try setting the default sink while two streams exists.
3498 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003499 if (kMaxUnsignaledRecvStreams > 1) {
3500 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3501 }
solenberg2100c0b2017-03-01 11:29:29 -08003502 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3503
3504 // Try setting the sink for the first unsignaled stream using its known SSRC.
3505 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003506 if (kMaxUnsignaledRecvStreams > 1) {
3507 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3508 }
solenberg2100c0b2017-03-01 11:29:29 -08003509 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003510 if (kMaxUnsignaledRecvStreams > 1) {
3511 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3512 }
deadbeef884f5852016-01-15 09:20:04 -08003513}
3514
skvlad7a43d252016-03-22 15:32:27 -07003515// Test that, just like the video channel, the voice channel communicates the
3516// network state to the call.
3517TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003518 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003519
3520 EXPECT_EQ(webrtc::kNetworkUp,
3521 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3522 EXPECT_EQ(webrtc::kNetworkUp,
3523 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3524
3525 channel_->OnReadyToSend(false);
3526 EXPECT_EQ(webrtc::kNetworkDown,
3527 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3528 EXPECT_EQ(webrtc::kNetworkUp,
3529 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3530
3531 channel_->OnReadyToSend(true);
3532 EXPECT_EQ(webrtc::kNetworkUp,
3533 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3534 EXPECT_EQ(webrtc::kNetworkUp,
3535 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3536}
3537
aleloi18e0b672016-10-04 02:45:47 -07003538// Test that playout is still started after changing parameters
3539TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3540 SetupRecvStream();
3541 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003542 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003543
3544 // Changing RTP header extensions will recreate the AudioReceiveStream.
3545 cricket::AudioRecvParameters parameters;
3546 parameters.extensions.push_back(
3547 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3548 channel_->SetRecvParameters(parameters);
3549
solenberg2100c0b2017-03-01 11:29:29 -08003550 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003551}
3552
stefan658910c2015-09-03 05:48:32 -07003553// Tests that the library initializes and shuts down properly.
3554TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003555 // If the VoiceEngine wants to gather available codecs early, that's fine but
3556 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003557 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003558 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003559 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003560 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003561 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003562 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3563 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003564 EXPECT_TRUE(channel != nullptr);
3565 delete channel;
solenbergff976312016-03-30 23:28:51 -07003566}
stefan658910c2015-09-03 05:48:32 -07003567
solenbergff976312016-03-30 23:28:51 -07003568// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003569TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3570 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3571 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3572 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003573 // Return 100ms just in case this function gets called. If we don't,
3574 // we could enter a tight loop since the mock would return 0.
3575 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003576 {
ossuc54071d2016-08-17 02:45:41 -07003577 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003578 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003579 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003580 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003581 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003582 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3583 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3584 EXPECT_TRUE(channel != nullptr);
3585 delete channel;
3586 }
stefan658910c2015-09-03 05:48:32 -07003587}
3588
3589// Tests that the library is configured with the codecs we want.
3590TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003591 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3592 // module.
3593
stefan658910c2015-09-03 05:48:32 -07003594 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003595#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003596 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003597 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003598#endif
3599#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003600 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003601 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003602#endif
3603#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003604 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003605 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003606#endif
3607#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003608 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003609 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003610 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003611 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003612 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003613#endif
solenberg26c8c912015-11-27 04:00:25 -08003614 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003615 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003616 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003617 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003618 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003619 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003620 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3621 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3622 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3623 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3624 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3625 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003626 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003627 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003628 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003629 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003630 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003631 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003632 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003633 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003634 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003635 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003636 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003637 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003638 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003639 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003640 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003641 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003642 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003643 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003644 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003649
stefan658910c2015-09-03 05:48:32 -07003650 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003651 // TODO(ossu): Why are the payload types of codecs with non-static payload
3652 // type assignments checked here? It shouldn't really matter.
3653 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003654 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003655 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3656 if (codec.name == "CN" && codec.clockrate == 16000) {
3657 EXPECT_EQ(105, codec.id);
3658 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3659 EXPECT_EQ(106, codec.id);
3660 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3661 EXPECT_EQ(103, codec.id);
3662 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3663 EXPECT_EQ(104, codec.id);
3664 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3665 EXPECT_EQ(9, codec.id);
3666 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3667 EXPECT_EQ(126, codec.id);
3668 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3669 // Remove these checks once both send and receive side assigns payload types
3670 // dynamically.
3671 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3672 EXPECT_EQ(113, codec.id);
3673 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3674 EXPECT_EQ(112, codec.id);
3675 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3676 EXPECT_EQ(110, codec.id);
3677 } else if (codec.name == "opus") {
3678 EXPECT_EQ(111, codec.id);
3679 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3680 EXPECT_EQ("10", codec.params.find("minptime")->second);
3681 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3682 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003683 }
3684 }
stefan658910c2015-09-03 05:48:32 -07003685}
3686
3687// Tests that VoE supports at least 32 channels
3688TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003689 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003690 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003691 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003692 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003693 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003694
3695 cricket::VoiceMediaChannel* channels[32];
3696 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003697 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003698 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3699 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003700 if (!channel)
3701 break;
stefan658910c2015-09-03 05:48:32 -07003702 channels[num_channels++] = channel;
3703 }
3704
tfarina5237aaf2015-11-10 23:44:30 -08003705 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003706 EXPECT_EQ(expected, num_channels);
3707
3708 while (num_channels > 0) {
3709 delete channels[--num_channels];
3710 }
stefan658910c2015-09-03 05:48:32 -07003711}
3712
3713// Test that we set our preferred codecs properly.
3714TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003715 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3716 // - Check that our builtin codecs are usable by Channel.
3717 // - The codecs provided by the engine is usable by Channel.
3718 // It does not check that the codecs in the RecvParameters are actually
3719 // what we sent in - though it's probably reasonable to expect so, if
3720 // SetRecvParameters returns true.
3721 // I think it will become clear once audio decoder injection is completed.
3722 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003723 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003724 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003725 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003726 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003727 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3728 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003729 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003730 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003731 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003732}
ossu9def8002017-02-09 05:14:32 -08003733
3734TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3735 std::vector<webrtc::AudioCodecSpec> specs;
3736 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3737 spec1.allow_comfort_noise = false;
3738 spec1.supports_network_adaption = true;
3739 specs.push_back(spec1);
3740 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3741 spec2.allow_comfort_noise = false;
3742 specs.push_back(spec2);
3743 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3744 {{"param1", "value1b"},
3745 {"param2", "value2"}}}));
3746 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3747 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3748
3749 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3750 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3751 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3752 .WillOnce(Return(specs));
3753
3754 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3755 auto codecs = engine.recv_codecs();
3756 EXPECT_EQ(11, codecs.size());
3757
3758 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3759 // check the actual values safely, to provide better test results.
3760 auto get_codec =
3761 [&codecs](size_t index) -> const cricket::AudioCodec& {
3762 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3763 if (codecs.size() > index)
3764 return codecs[index];
3765 return missing_codec;
3766 };
3767
3768 // Ensure the general codecs are generated first and in order.
3769 for (size_t i = 0; i != specs.size(); ++i) {
3770 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3771 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3772 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3773 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3774 }
3775
3776 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003777 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003778 auto find_codec =
3779 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3780 for (size_t i = 0; i != codecs.size(); ++i) {
3781 const cricket::AudioCodec& codec = codecs[i];
3782 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3783 codec.clockrate == format.clockrate_hz &&
3784 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003785 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003786 }
3787 }
3788 return -1;
3789 };
3790
3791 // Ensure all supplementary codecs are generated last. Their internal ordering
3792 // is not important.
3793 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3794 const int num_specs = static_cast<int>(specs.size());
3795 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3796 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3797 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3798 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3799 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3800 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3801 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3802}