blob: 544a4e42b7ff90d7ebe67467b03b2159d39db410 [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"
ossueb1fde42017-05-02 06:46:30 -070014#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080015#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000016#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080017#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080018#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070019#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080020#include "webrtc/media/base/fakemediaengine.h"
21#include "webrtc/media/base/fakenetworkinterface.h"
22#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080023#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010024#include "webrtc/media/engine/fakewebrtccall.h"
25#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
26#include "webrtc/media/engine/webrtcvoiceengine.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"
kwiberg37e99fd2017-04-10 05:15:48 -070032#include "webrtc/test/mock_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070033#include "webrtc/test/mock_audio_encoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080034#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
kwiberg1c07c702017-03-27 07:15:49 -070036using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070037using testing::Return;
38using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000039
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020040namespace {
41
solenbergebb349d2017-03-13 05:46:15 -070042constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
43
deadbeef67cf2c12016-04-13 10:07:16 -070044const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
45const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070046const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070047const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
48const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
50const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080051const cricket::AudioCodec
52 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
53const cricket::AudioCodec
54 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
55
solenberg2100c0b2017-03-01 11:29:29 -080056const uint32_t kSsrc0 = 0;
57const uint32_t kSsrc1 = 1;
58const uint32_t kSsrcX = 0x99;
59const uint32_t kSsrcY = 0x17;
60const uint32_t kSsrcZ = 0x42;
61const uint32_t kSsrcW = 0x02;
62const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063
solenberg971cab02016-06-14 10:02:41 -070064constexpr int kRtpHistoryMs = 5000;
65
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066class FakeVoEWrapper : public cricket::VoEWrapper {
67 public:
68 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070069 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070 }
71};
skvlad11a9cbf2016-10-07 11:53:05 -070072
solenberg76377c52017-02-21 00:54:31 -080073class MockTransmitMixer : public webrtc::voe::TransmitMixer {
74 public:
75 MockTransmitMixer() = default;
76 virtual ~MockTransmitMixer() = default;
77
78 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
79};
solenberg9a5f032222017-03-15 06:14:12 -070080
81void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
82 RTC_DCHECK(adm);
83 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
84 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
85#if !defined(WEBRTC_IOS)
86 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
87 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
88 ChannelType::kChannelBoth)).WillOnce(Return(0));
89#if defined(WEBRTC_WIN)
90 EXPECT_CALL(*adm, SetRecordingDevice(
91 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
92 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
93 .WillOnce(Return(0));
94#else
95 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
96#endif // #if defined(WEBRTC_WIN)
97 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
98 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
99 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
100 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
101#if defined(WEBRTC_WIN)
102 EXPECT_CALL(*adm, SetPlayoutDevice(
103 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
104 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
105 .WillOnce(Return(0));
106#else
107 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
108#endif // #if defined(WEBRTC_WIN)
109 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
110 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
111 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
112#endif // #if !defined(WEBRTC_IOS)
113 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
116 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
117}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200118} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119
solenbergff976312016-03-30 23:28:51 -0700120// Tests that our stub library "works".
121TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700122 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700123 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700124 StrictMock<webrtc::test::MockAudioProcessing> apm;
125 EXPECT_CALL(apm, ApplyConfig(testing::_));
126 EXPECT_CALL(apm, SetExtraOptions(testing::_));
127 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800128 StrictMock<MockTransmitMixer> transmit_mixer;
129 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
130 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700131 EXPECT_FALSE(voe.IsInited());
132 {
ossuc54071d2016-08-17 02:45:41 -0700133 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700134 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
135 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700136 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700137 EXPECT_TRUE(voe.IsInited());
138 }
139 EXPECT_FALSE(voe.IsInited());
140}
141
deadbeef884f5852016-01-15 09:20:04 -0800142class FakeAudioSink : public webrtc::AudioSinkInterface {
143 public:
144 void OnData(const Data& audio) override {}
145};
146
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800147class FakeAudioSource : public cricket::AudioSource {
148 void SetSink(Sink* sink) override {}
149};
150
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151class WebRtcVoiceEngineTestFake : public testing::Test {
152 public:
stefanba4c0e42016-02-04 04:12:24 -0800153 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
154
155 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800156 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
157 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
158 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700159 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800160 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700161 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800162 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700163 EXPECT_CALL(apm_, ApplyConfig(testing::_));
164 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
165 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800166 // Default Options.
167 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
168 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
169 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
170 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
171 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
172 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
173 // Init does not overwrite default AGC config.
174 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
175 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
176 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
177 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
178 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
179 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700180 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800181 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700182 // factories. Those tests should probably be moved elsewhere.
183 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
184 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
185 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
186 decoder_factory, nullptr,
187 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200188 send_parameters_.codecs.push_back(kPcmuCodec);
189 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800190 // Default Options.
191 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192 }
solenberg8189b022016-06-14 12:13:00 -0700193
solenbergff976312016-03-30 23:28:51 -0700194 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700195 EXPECT_CALL(apm_, ApplyConfig(testing::_));
196 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700197 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
198 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200199 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000200 }
solenberg8189b022016-06-14 12:13:00 -0700201
solenbergff976312016-03-30 23:28:51 -0700202 bool SetupRecvStream() {
203 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700204 return false;
205 }
solenberg2100c0b2017-03-01 11:29:29 -0800206 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700207 }
solenberg8189b022016-06-14 12:13:00 -0700208
solenbergff976312016-03-30 23:28:51 -0700209 bool SetupSendStream() {
210 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000211 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
solenberg2100c0b2017-03-01 11:29:29 -0800213 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800214 return false;
215 }
solenberg059fb442016-10-26 05:12:24 -0700216 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800217 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 }
solenberg8189b022016-06-14 12:13:00 -0700219
220 bool AddRecvStream(uint32_t ssrc) {
221 EXPECT_TRUE(channel_);
222 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
223 }
224
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000225 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700226 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700227 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800228 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
229 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700230 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800231 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700235 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000236 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 }
solenberg8189b022016-06-14 12:13:00 -0700238
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200239 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 }
242
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100243 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
244 const auto* send_stream = call_.GetAudioSendStream(ssrc);
245 EXPECT_TRUE(send_stream);
246 return *send_stream;
247 }
248
deadbeef884f5852016-01-15 09:20:04 -0800249 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
250 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
251 EXPECT_TRUE(recv_stream);
252 return *recv_stream;
253 }
254
solenberg3a941542015-11-16 07:34:50 -0800255 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800256 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800257 }
258
solenberg7add0582015-11-20 09:59:34 -0800259 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800260 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800261 }
262
solenberg059fb442016-10-26 05:12:24 -0700263 void SetSend(bool enable) {
264 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700265 if (enable) {
266 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
267 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
268 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700269 EXPECT_CALL(apm_, ApplyConfig(testing::_));
270 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700271 }
solenberg059fb442016-10-26 05:12:24 -0700272 channel_->SetSend(enable);
273 }
274
275 void SetSendParameters(const cricket::AudioSendParameters& params) {
276 EXPECT_CALL(apm_, ApplyConfig(testing::_));
277 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
278 ASSERT_TRUE(channel_);
279 EXPECT_TRUE(channel_->SetSendParameters(params));
280 }
281
minyue6b825df2016-10-31 04:08:32 -0700282 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
283 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700284 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
285 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700286 if (enable && options) {
287 EXPECT_CALL(apm_, ApplyConfig(testing::_));
288 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
289 }
290 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700291 }
292
solenbergffbbcac2016-11-17 05:25:37 -0800293 void TestInsertDtmf(uint32_t ssrc, bool caller,
294 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700295 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000296 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700297 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000298 // send stream.
299 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800300 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000301 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000302
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700304 SetSendParameters(send_parameters_);
305 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800307 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800308 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700309 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000311
312 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700313 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800314 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800316 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 }
318
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800320 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100322 // Test send.
323 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800324 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100325 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800327 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800328 EXPECT_EQ(codec.id, telephone_event.payload_type);
329 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100330 EXPECT_EQ(2, telephone_event.event_code);
331 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 }
333
334 // Test that send bandwidth is set correctly.
335 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000336 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
337 // |expected_result| is the expected result from SetMaxSendBandwidth().
338 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700339 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
340 int max_bitrate,
341 bool expected_result,
342 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200343 cricket::AudioSendParameters parameters;
344 parameters.codecs.push_back(codec);
345 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700346 if (expected_result) {
347 SetSendParameters(parameters);
348 } else {
349 EXPECT_FALSE(channel_->SetSendParameters(parameters));
350 }
solenberg2100c0b2017-03-01 11:29:29 -0800351 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
353
skvlade0d46372016-04-07 22:59:22 -0700354 // Sets the per-stream maximum bitrate limit for the specified SSRC.
355 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700356 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700357 EXPECT_EQ(1UL, parameters.encodings.size());
358
deadbeefe702b302017-02-04 12:09:01 -0800359 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700360 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700361 }
362
solenberg059fb442016-10-26 05:12:24 -0700363 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700364 cricket::AudioSendParameters send_parameters;
365 send_parameters.codecs.push_back(codec);
366 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700367 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700368 }
369
ossu20a4b3f2017-04-27 02:08:52 -0700370 void CheckSendCodecBitrate(int32_t ssrc,
371 const char expected_name[],
372 int expected_bitrate) {
373 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
374 EXPECT_EQ(expected_name, spec->format.name);
375 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700376 }
377
ossu20a4b3f2017-04-27 02:08:52 -0700378 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
379 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700380 }
381
minyue6b825df2016-10-31 04:08:32 -0700382 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
383 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
384 }
385
skvlade0d46372016-04-07 22:59:22 -0700386 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
387 int global_max,
388 int stream_max,
389 bool expected_result,
390 int expected_codec_bitrate) {
391 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800392 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700393
394 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700395 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800396 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700397
398 // Verify that reading back the parameters gives results
399 // consistent with the Set() result.
400 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800401 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700402 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
403 EXPECT_EQ(expected_result ? stream_max : -1,
404 resulting_parameters.encodings[0].max_bitrate_bps);
405
406 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800407 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700408 }
409
stefan13f1a0a2016-11-30 07:22:58 -0800410 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
411 int expected_min_bitrate_bps,
412 const char* start_bitrate_kbps,
413 int expected_start_bitrate_bps,
414 const char* max_bitrate_kbps,
415 int expected_max_bitrate_bps) {
416 EXPECT_TRUE(SetupSendStream());
417 auto& codecs = send_parameters_.codecs;
418 codecs.clear();
419 codecs.push_back(kOpusCodec);
420 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
421 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
422 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
423 SetSendParameters(send_parameters_);
424
425 EXPECT_EQ(expected_min_bitrate_bps,
426 call_.GetConfig().bitrate_config.min_bitrate_bps);
427 EXPECT_EQ(expected_start_bitrate_bps,
428 call_.GetConfig().bitrate_config.start_bitrate_bps);
429 EXPECT_EQ(expected_max_bitrate_bps,
430 call_.GetConfig().bitrate_config.max_bitrate_bps);
431 }
432
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000433 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700434 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000435
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000436 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800437 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000438
439 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700440 send_parameters_.extensions.push_back(
441 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700442 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800443 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000444
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000445 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200446 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700447 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800448 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000450 // Ensure extension is set properly.
451 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700452 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700453 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800454 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
455 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
456 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
solenberg7add0582015-11-20 09:59:34 -0800458 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000459 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800460 cricket::StreamParams::CreateLegacy(kSsrcY)));
461 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
462 call_.GetAudioSendStream(kSsrcY));
463 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
464 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
465 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000466
467 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200468 send_parameters_.codecs.push_back(kPcmuCodec);
469 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700470 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800471 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
472 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000473 }
474
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000475 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700476 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000477
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000478 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800479 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700482 recv_parameters_.extensions.push_back(
483 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800484 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000487 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800488 recv_parameters_.extensions.clear();
489 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000492 // Ensure extension is set properly.
493 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700494 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800495 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800496 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
497 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
498 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
solenberg7add0582015-11-20 09:59:34 -0800500 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_TRUE(AddRecvStream(kSsrcY));
502 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
503 call_.GetAudioReceiveStream(kSsrcY));
504 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
505 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
506 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000507
508 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800509 recv_parameters_.extensions.clear();
510 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
512 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000513 }
514
solenberg85a04962015-10-27 03:35:21 -0700515 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
516 webrtc::AudioSendStream::Stats stats;
517 stats.local_ssrc = 12;
518 stats.bytes_sent = 345;
519 stats.packets_sent = 678;
520 stats.packets_lost = 9012;
521 stats.fraction_lost = 34.56f;
522 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800523 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700524 stats.ext_seqnum = 789;
525 stats.jitter_ms = 12;
526 stats.rtt_ms = 345;
527 stats.audio_level = 678;
528 stats.aec_quality_min = 9.01f;
529 stats.echo_delay_median_ms = 234;
530 stats.echo_delay_std_ms = 567;
531 stats.echo_return_loss = 890;
532 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700533 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800534 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700535 stats.typing_noise_detected = true;
536 return stats;
537 }
538 void SetAudioSendStreamStats() {
539 for (auto* s : call_.GetAudioSendStreams()) {
540 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200541 }
solenberg85a04962015-10-27 03:35:21 -0700542 }
solenberg566ef242015-11-06 15:34:49 -0800543 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
544 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700545 const auto stats = GetAudioSendStreamStats();
546 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
547 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
548 EXPECT_EQ(info.packets_sent, stats.packets_sent);
549 EXPECT_EQ(info.packets_lost, stats.packets_lost);
550 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
551 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800552 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700553 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
554 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
555 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
556 EXPECT_EQ(info.audio_level, stats.audio_level);
557 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
558 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
559 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
560 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
561 EXPECT_EQ(info.echo_return_loss_enhancement,
562 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700563 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800564 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
565 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800566 EXPECT_EQ(info.typing_noise_detected,
567 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700568 }
569
570 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
571 webrtc::AudioReceiveStream::Stats stats;
572 stats.remote_ssrc = 123;
573 stats.bytes_rcvd = 456;
574 stats.packets_rcvd = 768;
575 stats.packets_lost = 101;
576 stats.fraction_lost = 23.45f;
577 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800578 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700579 stats.ext_seqnum = 678;
580 stats.jitter_ms = 901;
581 stats.jitter_buffer_ms = 234;
582 stats.jitter_buffer_preferred_ms = 567;
583 stats.delay_estimate_ms = 890;
584 stats.audio_level = 1234;
585 stats.expand_rate = 5.67f;
586 stats.speech_expand_rate = 8.90f;
587 stats.secondary_decoded_rate = 1.23f;
588 stats.accelerate_rate = 4.56f;
589 stats.preemptive_expand_rate = 7.89f;
590 stats.decoding_calls_to_silence_generator = 12;
591 stats.decoding_calls_to_neteq = 345;
592 stats.decoding_normal = 67890;
593 stats.decoding_plc = 1234;
594 stats.decoding_cng = 5678;
595 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700596 stats.decoding_muted_output = 3456;
597 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200598 return stats;
599 }
600 void SetAudioReceiveStreamStats() {
601 for (auto* s : call_.GetAudioReceiveStreams()) {
602 s->SetStats(GetAudioReceiveStreamStats());
603 }
604 }
605 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700606 const auto stats = GetAudioReceiveStreamStats();
607 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
608 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
609 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
610 EXPECT_EQ(info.packets_lost, stats.packets_lost);
611 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
612 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800613 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700614 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
615 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
616 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200617 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700618 stats.jitter_buffer_preferred_ms);
619 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
620 EXPECT_EQ(info.audio_level, stats.audio_level);
621 EXPECT_EQ(info.expand_rate, stats.expand_rate);
622 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
623 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
624 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
625 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200626 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700627 stats.decoding_calls_to_silence_generator);
628 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
629 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
630 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
631 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
632 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700633 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700634 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200635 }
hbos1acfbd22016-11-17 23:43:29 -0800636 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
637 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
638 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
639 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
640 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
641 codec.ToCodecParameters());
642 }
643 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
644 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
645 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
646 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
647 codec.ToCodecParameters());
648 }
649 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200650
peah8271d042016-11-22 07:24:52 -0800651 bool IsHighPassFilterEnabled() {
652 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
653 }
654
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700656 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700657 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800658 webrtc::test::MockGainControl& apm_gc_;
659 webrtc::test::MockEchoCancellation& apm_ec_;
660 webrtc::test::MockNoiseSuppression& apm_ns_;
661 webrtc::test::MockVoiceDetection& apm_vd_;
662 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700663 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200664 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700666 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700667 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200668 cricket::AudioSendParameters send_parameters_;
669 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800670 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800671 private:
672 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673};
674
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675// Tests that we can create and destroy a channel.
676TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700677 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678}
679
solenberg31fec402016-05-06 02:13:12 -0700680// Test that we can add a send stream and that it has the correct defaults.
681TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
682 EXPECT_TRUE(SetupChannel());
683 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800684 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
685 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
686 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700687 EXPECT_EQ("", config.rtp.c_name);
688 EXPECT_EQ(0u, config.rtp.extensions.size());
689 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
690 config.send_transport);
691}
692
693// Test that we can add a receive stream and that it has the correct defaults.
694TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
695 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800696 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700697 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800698 GetRecvStreamConfig(kSsrcX);
699 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700700 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
701 EXPECT_FALSE(config.rtp.transport_cc);
702 EXPECT_EQ(0u, config.rtp.extensions.size());
703 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
704 config.rtcp_send_transport);
705 EXPECT_EQ("", config.sync_group);
706}
707
stefanba4c0e42016-02-04 04:12:24 -0800708TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700709 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800710 bool opus_found = false;
711 for (cricket::AudioCodec codec : codecs) {
712 if (codec.name == "opus") {
713 EXPECT_TRUE(HasTransportCc(codec));
714 opus_found = true;
715 }
716 }
717 EXPECT_TRUE(opus_found);
718}
719
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720// Test that we set our inbound codecs properly, including changing PT.
721TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700722 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200723 cricket::AudioRecvParameters parameters;
724 parameters.codecs.push_back(kIsacCodec);
725 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800726 parameters.codecs.push_back(kTelephoneEventCodec1);
727 parameters.codecs.push_back(kTelephoneEventCodec2);
728 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200729 parameters.codecs[2].id = 126;
730 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800731 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700732 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
733 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
734 {{0, {"PCMU", 8000, 1}},
735 {106, {"ISAC", 16000, 1}},
736 {126, {"telephone-event", 8000, 1}},
737 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738}
739
740// Test that we fail to set an unknown inbound codec.
741TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700742 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200743 cricket::AudioRecvParameters parameters;
744 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700745 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200746 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747}
748
749// Test that we fail if we have duplicate types in the inbound list.
750TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700751 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200752 cricket::AudioRecvParameters parameters;
753 parameters.codecs.push_back(kIsacCodec);
754 parameters.codecs.push_back(kCn16000Codec);
755 parameters.codecs[1].id = kIsacCodec.id;
756 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757}
758
759// Test that we can decode OPUS without stereo parameters.
760TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700761 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200762 cricket::AudioRecvParameters parameters;
763 parameters.codecs.push_back(kIsacCodec);
764 parameters.codecs.push_back(kPcmuCodec);
765 parameters.codecs.push_back(kOpusCodec);
766 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800767 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700768 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
769 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
770 {{0, {"PCMU", 8000, 1}},
771 {103, {"ISAC", 16000, 1}},
772 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773}
774
775// Test that we can decode OPUS with stereo = 0.
776TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700777 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200778 cricket::AudioRecvParameters parameters;
779 parameters.codecs.push_back(kIsacCodec);
780 parameters.codecs.push_back(kPcmuCodec);
781 parameters.codecs.push_back(kOpusCodec);
782 parameters.codecs[2].params["stereo"] = "0";
783 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800784 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700785 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
786 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
787 {{0, {"PCMU", 8000, 1}},
788 {103, {"ISAC", 16000, 1}},
789 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
792// Test that we can decode OPUS with stereo = 1.
793TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700794 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 cricket::AudioRecvParameters parameters;
796 parameters.codecs.push_back(kIsacCodec);
797 parameters.codecs.push_back(kPcmuCodec);
798 parameters.codecs.push_back(kOpusCodec);
799 parameters.codecs[2].params["stereo"] = "1";
800 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800801 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700802 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
803 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
804 {{0, {"PCMU", 8000, 1}},
805 {103, {"ISAC", 16000, 1}},
806 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807}
808
809// Test that changes to recv codecs are applied to all streams.
810TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700811 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 cricket::AudioRecvParameters parameters;
813 parameters.codecs.push_back(kIsacCodec);
814 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800815 parameters.codecs.push_back(kTelephoneEventCodec1);
816 parameters.codecs.push_back(kTelephoneEventCodec2);
817 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 parameters.codecs[2].id = 126;
819 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700820 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
821 EXPECT_TRUE(AddRecvStream(ssrc));
822 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
823 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
824 {{0, {"PCMU", 8000, 1}},
825 {106, {"ISAC", 16000, 1}},
826 {126, {"telephone-event", 8000, 1}},
827 {107, {"telephone-event", 32000, 1}}})));
828 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829}
830
831TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700832 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200833 cricket::AudioRecvParameters parameters;
834 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800835 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200836 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837
solenberg2100c0b2017-03-01 11:29:29 -0800838 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800839 ASSERT_EQ(1, dm.count(106));
840 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can apply the same set of codecs again while playing.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kCn16000Codec);
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700850 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852
deadbeefcb383672017-04-26 16:28:42 -0700853 // Remapping a payload type to a different codec should fail.
854 parameters.codecs[0] = kOpusCodec;
855 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800857 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we can add a codec while playing.
861TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kCn16000Codec);
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700867 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200869 parameters.codecs.push_back(kOpusCodec);
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800871 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872}
873
deadbeefcb383672017-04-26 16:28:42 -0700874// Test that we accept adding the same codec with a different payload type.
875// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
876TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
877 EXPECT_TRUE(SetupRecvStream());
878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
881
882 ++parameters.codecs[0].id;
883 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
884}
885
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000886TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700887 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000889 // Test that when autobw is enabled, bitrate is kept as the default
890 // value. autobw is enabled for the following tests because the target
891 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892
893 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700894 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895
896 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700897 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898
ossu20a4b3f2017-04-27 02:08:52 -0700899 // opus, default bitrate == 32000 in mono.
900 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000903TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700904 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700907 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
908 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700909 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700912 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
913 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
914 // Rates above the max (510000) should be capped.
915 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916}
917
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000918TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700919 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000920
921 // Test that we can only set a maximum bitrate for a fixed-rate codec
922 // if it's bigger than the fixed rate.
923
924 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700925 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
926 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
927 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
928 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
929 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
930 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
931 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000932}
933
934TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200936 const int kDesiredBitrate = 128000;
937 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700938 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700940 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000941
942 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800943 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000944
solenberg2100c0b2017-03-01 11:29:29 -0800945 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000946}
947
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948// Test that bitrate cannot be set for CBR codecs.
949// Bitrate is ignored if it is higher than the fixed bitrate.
950// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953
954 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700955 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800956 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957
958 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700959 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800960 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200961
962 send_parameters_.max_bandwidth_bps = 128;
963 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800964 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965}
966
skvlade0d46372016-04-07 22:59:22 -0700967// Test that the per-stream bitrate limit and the global
968// bitrate limit both apply.
969TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
970 EXPECT_TRUE(SetupSendStream());
971
ossu20a4b3f2017-04-27 02:08:52 -0700972 // opus, default bitrate == 32000.
973 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700974 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
975 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
976 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
977
978 // CBR codecs allow both maximums to exceed the bitrate.
979 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
980 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
981 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
982 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
983
984 // CBR codecs don't allow per stream maximums to be too low.
985 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
986 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
987}
988
989// Test that an attempt to set RtpParameters for a stream that does not exist
990// fails.
991TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
992 EXPECT_TRUE(SetupChannel());
993 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800994 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700995 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
996
997 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -0800998 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -0700999}
1000
1001TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001002 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001003 // This test verifies that setting RtpParameters succeeds only if
1004 // the structure contains exactly one encoding.
1005 // TODO(skvlad): Update this test when we start supporting setting parameters
1006 // for each encoding individually.
1007
1008 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001009 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001010 // Two or more encodings should result in failure.
1011 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001013 // Zero encodings should also fail.
1014 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001016}
1017
1018// Changing the SSRC through RtpParameters is not allowed.
1019TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1020 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001021 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001022 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001023 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001024}
1025
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001026// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001027// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001028TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1029 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001030 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001031 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001032 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001033 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001034 ASSERT_EQ(1u, parameters.encodings.size());
1035 ASSERT_TRUE(parameters.encodings[0].active);
1036 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001037 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1038 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001039
1040 // Now change it back to active and verify we resume sending.
1041 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001042 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1043 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001044}
1045
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001046// Test that SetRtpSendParameters configures the correct encoding channel for
1047// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001048TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1049 SetupForMultiSendStream();
1050 // Create send streams.
1051 for (uint32_t ssrc : kSsrcs4) {
1052 EXPECT_TRUE(
1053 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1054 }
1055 // Configure one stream to be limited by the stream config, another to be
1056 // limited by the global max, and the third one with no per-stream limit
1057 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001058 SetGlobalMaxBitrate(kOpusCodec, 32000);
1059 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1060 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001061 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1062
ossu20a4b3f2017-04-27 02:08:52 -07001063 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1064 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1065 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001066
1067 // Remove the global cap; the streams should switch to their respective
1068 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001069 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001070 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1071 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1072 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001073}
1074
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075// Test that GetRtpSendParameters returns the currently configured codecs.
1076TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001077 EXPECT_TRUE(SetupSendStream());
1078 cricket::AudioSendParameters parameters;
1079 parameters.codecs.push_back(kIsacCodec);
1080 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001081 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001082
solenberg2100c0b2017-03-01 11:29:29 -08001083 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001084 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001085 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1086 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001087}
1088
deadbeefcb443432016-12-12 11:12:36 -08001089// Test that GetRtpSendParameters returns an SSRC.
1090TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1091 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001092 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001093 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001094 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001095}
1096
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001097// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001098TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001099 EXPECT_TRUE(SetupSendStream());
1100 cricket::AudioSendParameters parameters;
1101 parameters.codecs.push_back(kIsacCodec);
1102 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001103 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001104
solenberg2100c0b2017-03-01 11:29:29 -08001105 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001106
1107 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001109
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001110 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001111 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1112 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001113}
1114
minyuececec102017-03-27 13:04:25 -07001115// Test that max_bitrate_bps in send stream config gets updated correctly when
1116// SetRtpSendParameters is called.
1117TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1118 webrtc::test::ScopedFieldTrials override_field_trials(
1119 "WebRTC-Audio-SendSideBwe/Enabled/");
1120 EXPECT_TRUE(SetupSendStream());
1121 cricket::AudioSendParameters send_parameters;
1122 send_parameters.codecs.push_back(kOpusCodec);
1123 SetSendParameters(send_parameters);
1124
1125 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1126 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1127 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1128
1129 constexpr int kMaxBitrateBps = 6000;
1130 rtp_parameters.encodings[0].max_bitrate_bps =
1131 rtc::Optional<int>(kMaxBitrateBps);
1132 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1133
1134 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1135 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1136}
1137
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001138// Test that GetRtpReceiveParameters returns the currently configured codecs.
1139TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1140 EXPECT_TRUE(SetupRecvStream());
1141 cricket::AudioRecvParameters parameters;
1142 parameters.codecs.push_back(kIsacCodec);
1143 parameters.codecs.push_back(kPcmuCodec);
1144 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1145
1146 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001147 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001148 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1149 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1150 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1151}
1152
deadbeefcb443432016-12-12 11:12:36 -08001153// Test that GetRtpReceiveParameters returns an SSRC.
1154TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1155 EXPECT_TRUE(SetupRecvStream());
1156 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001157 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001158 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001159 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001160}
1161
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001162// Test that if we set/get parameters multiple times, we get the same results.
1163TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1164 EXPECT_TRUE(SetupRecvStream());
1165 cricket::AudioRecvParameters parameters;
1166 parameters.codecs.push_back(kIsacCodec);
1167 parameters.codecs.push_back(kPcmuCodec);
1168 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1169
1170 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001171 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001172
1173 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001174 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001175
1176 // ... And this shouldn't change the params returned by
1177 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001178 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1179 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001180}
1181
deadbeef3bc15102017-04-20 19:25:07 -07001182// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1183// aren't signaled. It should return an empty "RtpEncodingParameters" when
1184// configured to receive an unsignaled stream and no packets have been received
1185// yet, and start returning the SSRC once a packet has been received.
1186TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1187 ASSERT_TRUE(SetupChannel());
1188 // Call necessary methods to configure receiving a default stream as
1189 // soon as it arrives.
1190 cricket::AudioRecvParameters parameters;
1191 parameters.codecs.push_back(kIsacCodec);
1192 parameters.codecs.push_back(kPcmuCodec);
1193 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1194
1195 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1196 // stream. Should return nothing.
1197 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1198
1199 // Set a sink for an unsignaled stream.
1200 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1201 // Value of "0" means "unsignaled stream".
1202 channel_->SetRawAudioSink(0, std::move(fake_sink));
1203
1204 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1205 // in this method means "unsignaled stream".
1206 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1207 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1208 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1209
1210 // Receive PCMU packet (SSRC=1).
1211 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1212
1213 // The |ssrc| member should still be unset.
1214 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1215 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1216 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1217}
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;
ossu20a4b3f2017-04-27 02:08:52 -07001227 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001228 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001229 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1230 EXPECT_EQ(96, send_codec_spec.payload_type);
1231 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1232 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1233 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1234 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001235 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001236}
1237
ossu20a4b3f2017-04-27 02:08:52 -07001238// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1239// AudioSendStream.
1240TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001241 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001242 cricket::AudioSendParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001245 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001246 parameters.codecs[0].id = 96;
1247 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001248 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001249 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001250 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001251 // Calling SetSendCodec again with same codec which is already set.
1252 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001253 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001254 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001255}
1256
ossu20a4b3f2017-04-27 02:08:52 -07001257// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1258// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001259
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001260// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001261TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001262 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001263 cricket::AudioSendParameters parameters;
1264 parameters.codecs.push_back(kOpusCodec);
1265 parameters.codecs[0].bitrate = 0;
1266 parameters.codecs[0].clockrate = 50000;
1267 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001268}
1269
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001270// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001271TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001272 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 cricket::AudioSendParameters parameters;
1274 parameters.codecs.push_back(kOpusCodec);
1275 parameters.codecs[0].bitrate = 0;
1276 parameters.codecs[0].channels = 0;
1277 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278}
1279
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001280// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001281TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001282 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001283 cricket::AudioSendParameters parameters;
1284 parameters.codecs.push_back(kOpusCodec);
1285 parameters.codecs[0].bitrate = 0;
1286 parameters.codecs[0].channels = 0;
1287 parameters.codecs[0].params["stereo"] = "1";
1288 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001289}
1290
1291// Test that if channel is 1 for opus and there's no stereo, we fail.
1292TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
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 = 1;
1298 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001299}
1300
1301// Test that if channel is 1 for opus and stereo=0, we fail.
1302TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001303 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001304 cricket::AudioSendParameters parameters;
1305 parameters.codecs.push_back(kOpusCodec);
1306 parameters.codecs[0].bitrate = 0;
1307 parameters.codecs[0].channels = 1;
1308 parameters.codecs[0].params["stereo"] = "0";
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=1, we fail.
1313TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
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"] = "1";
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
ossu20a4b3f2017-04-27 02:08:52 -07001323// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
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;
solenberg059fb442016-10-26 05:12:24 -07001329 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001330 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331}
1332
ossu20a4b3f2017-04-27 02:08:52 -07001333// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001335 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001336 cricket::AudioSendParameters parameters;
1337 parameters.codecs.push_back(kOpusCodec);
1338 parameters.codecs[0].bitrate = 0;
1339 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001340 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001341 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001342}
1343
ossu20a4b3f2017-04-27 02:08:52 -07001344// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001345TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001346 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001347 cricket::AudioSendParameters parameters;
1348 parameters.codecs.push_back(kOpusCodec);
1349 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001350 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001353 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001354
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001356 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001357 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001358}
1359
ossu20a4b3f2017-04-27 02:08:52 -07001360// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001362 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 cricket::AudioSendParameters parameters;
1364 parameters.codecs.push_back(kOpusCodec);
1365 parameters.codecs[0].bitrate = 0;
1366 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001367 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001368 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001369}
1370
ossu20a4b3f2017-04-27 02:08:52 -07001371// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001377 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001379 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001380 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001381
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001383 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001384 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001385}
1386
ossu20a4b3f2017-04-27 02:08:52 -07001387// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001389 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 cricket::AudioSendParameters parameters;
1391 parameters.codecs.push_back(kOpusCodec);
1392 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001394 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1395 EXPECT_EQ(111, spec.payload_type);
1396 EXPECT_EQ(96000, spec.target_bitrate_bps);
1397 EXPECT_EQ("opus", spec.format.name);
1398 EXPECT_EQ(2, spec.format.num_channels);
1399 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400}
1401
ossu20a4b3f2017-04-27 02:08:52 -07001402// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001404 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 cricket::AudioSendParameters parameters;
1406 parameters.codecs.push_back(kOpusCodec);
1407 parameters.codecs[0].bitrate = 30000;
1408 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001409 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001410 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001411}
1412
ossu20a4b3f2017-04-27 02:08:52 -07001413// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001415 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kOpusCodec);
1418 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001419 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001420 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001421}
1422
ossu20a4b3f2017-04-27 02:08:52 -07001423// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001425 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001426 cricket::AudioSendParameters parameters;
1427 parameters.codecs.push_back(kOpusCodec);
1428 parameters.codecs[0].bitrate = 30000;
1429 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001430 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001431 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001432}
1433
stefan13f1a0a2016-11-30 07:22:58 -08001434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1435 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1436 200000);
1437}
1438
1439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1440 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1441}
1442
1443TEST_F(WebRtcVoiceEngineTestFake,
1444 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1445 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1446}
1447
1448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1449 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1450}
1451
1452TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001453 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001454 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1455 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001456 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001457 SetSendParameters(send_parameters_);
1458 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1459 << "Setting max bitrate should keep previous min bitrate.";
1460 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1461 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001462 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001463}
1464
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001465// Test that we can enable NACK with opus as caller.
1466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].AddFeedbackParam(
1471 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1472 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001473 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001474 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001475 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476}
1477
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001478// Test that we can enable NACK with opus as callee.
1479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].AddFeedbackParam(
1484 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1485 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001486 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001487 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001488 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001489 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001490
1491 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001492 cricket::StreamParams::CreateLegacy(kSsrcX)));
1493 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001494}
1495
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001496// Test that we can enable NACK on receive streams.
1497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001499 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001500 cricket::AudioSendParameters parameters;
1501 parameters.codecs.push_back(kOpusCodec);
1502 parameters.codecs[0].AddFeedbackParam(
1503 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1504 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001505 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1506 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001508 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1509 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001510}
1511
1512// Test that we can disable NACK.
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001514 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001515 cricket::AudioSendParameters parameters;
1516 parameters.codecs.push_back(kOpusCodec);
1517 parameters.codecs[0].AddFeedbackParam(
1518 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1519 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001520 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001523 parameters.codecs.clear();
1524 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001526 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
1529// Test that we can disable NACK on receive streams.
1530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001532 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001538 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001539 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1540 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001542 parameters.codecs.clear();
1543 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001544 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001545 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1546 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
1549// Test that NACK is enabled on a new receive stream.
1550TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001551 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 cricket::AudioSendParameters parameters;
1553 parameters.codecs.push_back(kIsacCodec);
1554 parameters.codecs.push_back(kCn16000Codec);
1555 parameters.codecs[0].AddFeedbackParam(
1556 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1557 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001558 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_TRUE(AddRecvStream(kSsrcY));
1562 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1563 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1564 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565}
1566
stefanba4c0e42016-02-04 04:12:24 -08001567TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001569 cricket::AudioSendParameters send_parameters;
1570 send_parameters.codecs.push_back(kOpusCodec);
1571 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001573
1574 cricket::AudioRecvParameters recv_parameters;
1575 recv_parameters.codecs.push_back(kIsacCodec);
1576 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_TRUE(AddRecvStream(kSsrcX));
1578 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001579 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001580 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001581
ossudedfd282016-06-14 07:12:39 -07001582 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001584 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001585 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001586 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001587}
1588
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001589// Test that we can switch back and forth between Opus and ISAC with CN.
1590TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001591 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001592
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 cricket::AudioSendParameters opus_parameters;
1594 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001595 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001596 {
ossu20a4b3f2017-04-27 02:08:52 -07001597 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1598 EXPECT_EQ(111, spec.payload_type);
1599 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001600 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001602 cricket::AudioSendParameters isac_parameters;
1603 isac_parameters.codecs.push_back(kIsacCodec);
1604 isac_parameters.codecs.push_back(kCn16000Codec);
1605 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001606 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001607 {
ossu20a4b3f2017-04-27 02:08:52 -07001608 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1609 EXPECT_EQ(103, spec.payload_type);
1610 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001611 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612
solenberg059fb442016-10-26 05:12:24 -07001613 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001614 {
ossu20a4b3f2017-04-27 02:08:52 -07001615 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1616 EXPECT_EQ(111, spec.payload_type);
1617 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001618 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619}
1620
1621// Test that we handle various ways of specifying bitrate.
1622TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001623 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 cricket::AudioSendParameters parameters;
1625 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001627 {
ossu20a4b3f2017-04-27 02:08:52 -07001628 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1629 EXPECT_EQ(103, spec.payload_type);
1630 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1631 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001632 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001633
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001634 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001636 {
ossu20a4b3f2017-04-27 02:08:52 -07001637 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1638 EXPECT_EQ(103, spec.payload_type);
1639 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1640 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001641 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001642 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001643 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001644 {
ossu20a4b3f2017-04-27 02:08:52 -07001645 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1646 EXPECT_EQ(103, spec.payload_type);
1647 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1648 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001649 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001650
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001651 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001652 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001653 {
ossu20a4b3f2017-04-27 02:08:52 -07001654 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1655 EXPECT_EQ(0, spec.payload_type);
1656 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1657 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001658 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001659
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001660 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001661 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001662 {
ossu20a4b3f2017-04-27 02:08:52 -07001663 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1664 EXPECT_EQ(0, spec.payload_type);
1665 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1666 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001667 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 parameters.codecs[0] = kOpusCodec;
1670 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001672 {
ossu20a4b3f2017-04-27 02:08:52 -07001673 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1674 EXPECT_EQ(111, spec.payload_type);
1675 EXPECT_STREQ("opus", spec.format.name.c_str());
1676 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001677 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678}
1679
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001680// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001682 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001683 cricket::AudioSendParameters parameters;
1684 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001685}
1686
1687// Test that we can set send codecs even with telephone-event codec as the first
1688// one on the list.
1689TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001690 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001691 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001692 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 parameters.codecs.push_back(kIsacCodec);
1694 parameters.codecs.push_back(kPcmuCodec);
1695 parameters.codecs[0].id = 98; // DTMF
1696 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001697 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001698 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1699 EXPECT_EQ(96, spec.payload_type);
1700 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001701 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001702}
1703
solenberg31642aa2016-03-14 08:00:37 -07001704// Test that payload type range is limited for telephone-event codec.
1705TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001706 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001707 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001708 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001709 parameters.codecs.push_back(kIsacCodec);
1710 parameters.codecs[0].id = 0; // DTMF
1711 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001713 EXPECT_TRUE(channel_->CanInsertDtmf());
1714 parameters.codecs[0].id = 128; // DTMF
1715 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1716 EXPECT_FALSE(channel_->CanInsertDtmf());
1717 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001718 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001719 EXPECT_TRUE(channel_->CanInsertDtmf());
1720 parameters.codecs[0].id = -1; // DTMF
1721 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1722 EXPECT_FALSE(channel_->CanInsertDtmf());
1723}
1724
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001725// Test that we can set send codecs even with CN codec as the first
1726// one on the list.
1727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001729 cricket::AudioSendParameters parameters;
1730 parameters.codecs.push_back(kCn16000Codec);
1731 parameters.codecs.push_back(kIsacCodec);
1732 parameters.codecs.push_back(kPcmuCodec);
1733 parameters.codecs[0].id = 98; // wideband CN
1734 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001735 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001736 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1737 EXPECT_EQ(96, send_codec_spec.payload_type);
1738 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001739 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001740}
1741
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001742// Test that we set VAD and DTMF types correctly as caller.
1743TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001744 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 cricket::AudioSendParameters parameters;
1746 parameters.codecs.push_back(kIsacCodec);
1747 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001748 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 parameters.codecs.push_back(kCn16000Codec);
1750 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001751 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001752 parameters.codecs[0].id = 96;
1753 parameters.codecs[2].id = 97; // wideband CN
1754 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001756 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1757 EXPECT_EQ(96, send_codec_spec.payload_type);
1758 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1759 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001760 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001761 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001762}
1763
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001764// Test that we set VAD and DTMF types correctly as callee.
1765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kIsacCodec);
1769 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001770 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 parameters.codecs.push_back(kCn16000Codec);
1772 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001773 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001774 parameters.codecs[0].id = 96;
1775 parameters.codecs[2].id = 97; // wideband CN
1776 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001778 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001779 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001780
ossu20a4b3f2017-04-27 02:08:52 -07001781 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1782 EXPECT_EQ(96, send_codec_spec.payload_type);
1783 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1784 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001785 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001786 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001787}
1788
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789// Test that we only apply VAD if we have a CN codec that matches the
1790// send codec clockrate.
1791TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001792 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001793 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs.push_back(kIsacCodec);
1796 parameters.codecs.push_back(kCn16000Codec);
1797 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001799 {
ossu20a4b3f2017-04-27 02:08:52 -07001800 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1801 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1802 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001803 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001804 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001806 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001808 {
ossu20a4b3f2017-04-27 02:08:52 -07001809 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1810 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1811 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001812 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 {
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1819 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001820 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001821 }
Brave Yao5225dd82015-03-26 07:39:19 +08001822 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001824 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001825 {
ossu20a4b3f2017-04-27 02:08:52 -07001826 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1827 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1828 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001829 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001830}
1831
1832// Test that we perform case-insensitive matching of codec names.
1833TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001834 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001835 cricket::AudioSendParameters parameters;
1836 parameters.codecs.push_back(kIsacCodec);
1837 parameters.codecs.push_back(kPcmuCodec);
1838 parameters.codecs.push_back(kCn16000Codec);
1839 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001840 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 parameters.codecs[0].name = "iSaC";
1842 parameters.codecs[0].id = 96;
1843 parameters.codecs[2].id = 97; // wideband CN
1844 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001845 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_EQ(96, send_codec_spec.payload_type);
1848 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1849 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001850 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001851 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852}
1853
stefanba4c0e42016-02-04 04:12:24 -08001854class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1855 public:
1856 WebRtcVoiceEngineWithSendSideBweTest()
1857 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1858};
1859
1860TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1861 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001862 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001863 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001864 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1865 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1866 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001867 extension.id);
1868 return;
1869 }
1870 }
1871 FAIL() << "Transport sequence number extension not in header-extension list.";
1872}
1873
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001874// Test support for audio level header extension.
1875TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001876 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001877}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001878TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001879 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001880}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001881
solenbergd4adce42016-11-17 06:26:52 -08001882// Test support for transport sequence number header extension.
1883TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1884 TestSetSendRtpHeaderExtensions(
1885 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001886}
solenbergd4adce42016-11-17 06:26:52 -08001887TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1888 TestSetRecvRtpHeaderExtensions(
1889 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890}
1891
solenberg1ac56142015-10-13 03:58:19 -07001892// Test that we can create a channel and start sending on it.
1893TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001894 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001895 SetSendParameters(send_parameters_);
1896 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001897 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001898 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001899 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001900}
1901
1902// Test that a channel will send if and only if it has a source and is enabled
1903// for sending.
1904TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001905 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001906 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001907 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001908 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001909 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1910 SetAudioSend(kSsrcX, true, &fake_source_);
1911 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1912 SetAudioSend(kSsrcX, true, nullptr);
1913 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001914}
1915
solenberg94218532016-06-16 10:53:22 -07001916// Test that a channel is muted/unmuted.
1917TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1918 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001919 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001920 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1921 SetAudioSend(kSsrcX, true, nullptr);
1922 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1923 SetAudioSend(kSsrcX, false, nullptr);
1924 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001925}
1926
solenberg6d6e7c52016-04-13 09:07:30 -07001927// Test that SetSendParameters() does not alter a stream's send state.
1928TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1929 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001930 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001931
1932 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001933 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001934 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001935
1936 // Changing RTP header extensions will recreate the AudioSendStream.
1937 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001938 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001939 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001940 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001941
1942 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001943 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001944 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001945
1946 // Changing RTP header extensions will recreate the AudioSendStream.
1947 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001948 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001949 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001950}
1951
solenberg1ac56142015-10-13 03:58:19 -07001952// Test that we can create a channel and start playing out on it.
1953TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001954 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001955 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001956 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001957 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001958 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001959 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960}
1961
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001962// Test that we can add and remove send streams.
1963TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1964 SetupForMultiSendStream();
1965
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001966 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001967 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001968
solenbergc96df772015-10-21 13:01:53 -07001969 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001970 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001971 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001972 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001973 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001974 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001975 }
tfarina5237aaf2015-11-10 23:44:30 -08001976 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001977
solenbergc96df772015-10-21 13:01:53 -07001978 // Delete the send streams.
1979 for (uint32_t ssrc : kSsrcs4) {
1980 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001981 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001982 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001983 }
solenbergc96df772015-10-21 13:01:53 -07001984 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001985}
1986
1987// Test SetSendCodecs correctly configure the codecs in all send streams.
1988TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1989 SetupForMultiSendStream();
1990
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001991 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07001992 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001993 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001994 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 }
1996
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001998 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs.push_back(kIsacCodec);
2000 parameters.codecs.push_back(kCn16000Codec);
2001 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002002 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002003
2004 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002005 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002006 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2007 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002008 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2009 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2010 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002011 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002012 }
2013
minyue7a973442016-10-20 03:27:12 -07002014 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002015 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002017 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002018 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2019 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002020 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2021 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2022 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023 }
2024}
2025
2026// Test we can SetSend on all send streams correctly.
2027TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2028 SetupForMultiSendStream();
2029
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002030 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002031 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002032 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002033 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002034 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002035 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 }
2037
2038 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002039 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002040 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002042 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 }
2044
2045 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002046 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002047 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002049 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 }
2051}
2052
2053// Test we can set the correct statistics on all send streams.
2054TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2055 SetupForMultiSendStream();
2056
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002057 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002058 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002060 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 }
solenberg85a04962015-10-27 03:35:21 -07002062
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002063 // Create a receive stream to check that none of the send streams end up in
2064 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002065 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002066
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002067 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002069 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002070 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071
solenberg85a04962015-10-27 03:35:21 -07002072 // Check stats for the added streams.
2073 {
2074 cricket::VoiceMediaInfo info;
2075 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002076
solenberg85a04962015-10-27 03:35:21 -07002077 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002078 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002079 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002080 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002081 }
hbos1acfbd22016-11-17 23:43:29 -08002082 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002083
2084 // We have added one receive stream. We should see empty stats.
2085 EXPECT_EQ(info.receivers.size(), 1u);
2086 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 }
solenberg1ac56142015-10-13 03:58:19 -07002088
solenberg2100c0b2017-03-01 11:29:29 -08002089 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002090 {
2091 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002092 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002093 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002094 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002095 EXPECT_EQ(0u, info.receivers.size());
2096 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002097
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002098 // Deliver a new packet - a default receive stream should be created and we
2099 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002100 {
2101 cricket::VoiceMediaInfo info;
2102 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2103 SetAudioReceiveStreamStats();
2104 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002105 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002106 EXPECT_EQ(1u, info.receivers.size());
2107 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002108 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002109 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110}
2111
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112// Test that we can add and remove receive streams, and do proper send/playout.
2113// We can receive on multiple streams while sending one stream.
2114TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002115 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002116
solenberg1ac56142015-10-13 03:58:19 -07002117 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002118 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002119 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120
solenberg1ac56142015-10-13 03:58:19 -07002121 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002122 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002123 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002124 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002125
solenberg1ac56142015-10-13 03:58:19 -07002126 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002127 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002128
2129 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2131 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2132 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002133
2134 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002135 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002136 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137
2138 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002139 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002140 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2141 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002142
aleloi84ef6152016-08-04 05:28:21 -07002143 // Restart playout and make sure recv streams are played out.
2144 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002145 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2146 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002147
aleloi84ef6152016-08-04 05:28:21 -07002148 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002149 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2150 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002151}
2152
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002154// and start sending on it.
2155TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002156 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002157 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2158 EXPECT_CALL(apm_gc_,
2159 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002160 SetSendParameters(send_parameters_);
2161 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002162 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002163 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002164 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002165}
2166
wu@webrtc.org97077a32013-10-25 21:18:33 +00002167TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002168 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002169 EXPECT_CALL(adm_,
2170 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002171 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2172 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002173 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2174 send_parameters_.options.tx_agc_digital_compression_gain =
2175 rtc::Optional<uint16_t>(9);
2176 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2177 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002178 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2179 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2180 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002181 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002182
2183 // Check interaction with adjust_agc_delta. Both should be respected, for
2184 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002185 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002186 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002187 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002188}
2189
wu@webrtc.org97077a32013-10-25 21:18:33 +00002190TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002191 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002192 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2193 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002194 send_parameters_.options.recording_sample_rate =
2195 rtc::Optional<uint32_t>(48000);
2196 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002197 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002198}
2199
minyue6b825df2016-10-31 04:08:32 -07002200TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2201 EXPECT_TRUE(SetupSendStream());
2202 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2203 send_parameters_.options.audio_network_adaptor_config =
2204 rtc::Optional<std::string>("1234");
2205 SetSendParameters(send_parameters_);
2206 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002207 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002208}
2209
2210TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2211 EXPECT_TRUE(SetupSendStream());
2212 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2213 send_parameters_.options.audio_network_adaptor_config =
2214 rtc::Optional<std::string>("1234");
2215 SetSendParameters(send_parameters_);
2216 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002217 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002218 cricket::AudioOptions options;
2219 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002220 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002221 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002222}
2223
2224TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2225 EXPECT_TRUE(SetupSendStream());
2226 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2227 send_parameters_.options.audio_network_adaptor_config =
2228 rtc::Optional<std::string>("1234");
2229 SetSendParameters(send_parameters_);
2230 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002231 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002232 const int initial_num = call_.GetNumCreatedSendStreams();
2233 cricket::AudioOptions options;
2234 options.audio_network_adaptor = rtc::Optional<bool>();
2235 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2236 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002237 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002238 // AudioSendStream not expected to be recreated.
2239 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2240 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002241 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002242}
2243
michaelt6672b262017-01-11 10:17:59 -08002244class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2245 : public WebRtcVoiceEngineTestFake {
2246 public:
2247 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2248 : WebRtcVoiceEngineTestFake(
2249 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2250 "Enabled/") {}
2251};
2252
2253TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2254 EXPECT_TRUE(SetupSendStream());
2255 cricket::AudioSendParameters parameters;
2256 parameters.codecs.push_back(kOpusCodec);
2257 SetSendParameters(parameters);
2258 const int initial_num = call_.GetNumCreatedSendStreams();
2259 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2260
2261 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2262 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002263 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2264 constexpr int kMinOverheadBps =
2265 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002266
2267 constexpr int kOpusMinBitrateBps = 6000;
2268 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002269 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002270 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002271 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002272 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002273
2274 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2275 parameters.options.audio_network_adaptor_config =
2276 rtc::Optional<std::string>("1234");
2277 SetSendParameters(parameters);
2278
ossu11bfc532017-02-16 05:37:06 -08002279 constexpr int kMinOverheadWithAnaBps =
2280 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002281
2282 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002283 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002284
minyuececec102017-03-27 13:04:25 -07002285 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002286 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002287}
2288
minyuececec102017-03-27 13:04:25 -07002289// This test is similar to
2290// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2291// additional field trial.
2292TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2293 SetRtpSendParameterUpdatesMaxBitrate) {
2294 EXPECT_TRUE(SetupSendStream());
2295 cricket::AudioSendParameters send_parameters;
2296 send_parameters.codecs.push_back(kOpusCodec);
2297 SetSendParameters(send_parameters);
2298
2299 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2300 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2301 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2302
2303 constexpr int kMaxBitrateBps = 6000;
2304 rtp_parameters.encodings[0].max_bitrate_bps =
2305 rtc::Optional<int>(kMaxBitrateBps);
2306 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2307
2308 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2309#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2310 constexpr int kMinOverhead = 3333;
2311#else
2312 constexpr int kMinOverhead = 6666;
2313#endif
2314 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2315}
2316
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002318// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002319TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002320 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002321 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002322}
2323
2324TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2325 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002326 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002327 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002328 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002329 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002330 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002331 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002332 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002333
solenberg85a04962015-10-27 03:35:21 -07002334 // Check stats for the added streams.
2335 {
2336 cricket::VoiceMediaInfo info;
2337 EXPECT_EQ(true, channel_->GetStats(&info));
2338
2339 // We have added one send stream. We should see the stats we've set.
2340 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002341 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002342 // We have added one receive stream. We should see empty stats.
2343 EXPECT_EQ(info.receivers.size(), 1u);
2344 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2345 }
solenberg1ac56142015-10-13 03:58:19 -07002346
solenberg566ef242015-11-06 15:34:49 -08002347 // Start sending - this affects some reported stats.
2348 {
2349 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002350 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002351 EXPECT_EQ(true, channel_->GetStats(&info));
2352 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002353 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002354 }
2355
solenberg2100c0b2017-03-01 11:29:29 -08002356 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002357 {
2358 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002359 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002360 EXPECT_EQ(true, channel_->GetStats(&info));
2361 EXPECT_EQ(1u, info.senders.size());
2362 EXPECT_EQ(0u, info.receivers.size());
2363 }
solenberg1ac56142015-10-13 03:58:19 -07002364
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002365 // Deliver a new packet - a default receive stream should be created and we
2366 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002367 {
2368 cricket::VoiceMediaInfo info;
2369 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2370 SetAudioReceiveStreamStats();
2371 EXPECT_EQ(true, channel_->GetStats(&info));
2372 EXPECT_EQ(1u, info.senders.size());
2373 EXPECT_EQ(1u, info.receivers.size());
2374 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002375 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002376 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002377}
2378
2379// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002380// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002382 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002383 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2384 EXPECT_TRUE(AddRecvStream(kSsrcY));
2385 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002386}
2387
2388// Test that the local SSRC is the same on sending and receiving channels if the
2389// receive channel is created before the send channel.
2390TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002391 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002392 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002393 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002394 cricket::StreamParams::CreateLegacy(kSsrcX)));
2395 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2396 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397}
2398
2399// Test that we can properly receive packets.
2400TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002401 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002402 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002403 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002404
2405 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2406 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002407}
2408
2409// Test that we can properly receive packets on multiple streams.
2410TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002411 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002412 const uint32_t ssrc1 = 1;
2413 const uint32_t ssrc2 = 2;
2414 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002415 EXPECT_TRUE(AddRecvStream(ssrc1));
2416 EXPECT_TRUE(AddRecvStream(ssrc2));
2417 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002419 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002420 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002422 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423 }
mflodman3d7db262016-04-29 00:57:13 -07002424
2425 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2426 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2427 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2428
2429 EXPECT_EQ(s1.received_packets(), 0);
2430 EXPECT_EQ(s2.received_packets(), 0);
2431 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002432
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002434 EXPECT_EQ(s1.received_packets(), 0);
2435 EXPECT_EQ(s2.received_packets(), 0);
2436 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002437
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002439 EXPECT_EQ(s1.received_packets(), 1);
2440 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2441 EXPECT_EQ(s2.received_packets(), 0);
2442 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002443
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002445 EXPECT_EQ(s1.received_packets(), 1);
2446 EXPECT_EQ(s2.received_packets(), 1);
2447 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2448 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002449
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002451 EXPECT_EQ(s1.received_packets(), 1);
2452 EXPECT_EQ(s2.received_packets(), 1);
2453 EXPECT_EQ(s3.received_packets(), 1);
2454 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002455
mflodman3d7db262016-04-29 00:57:13 -07002456 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2457 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2458 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459}
2460
solenberg2100c0b2017-03-01 11:29:29 -08002461// Test that receiving on an unsignaled stream works (a stream is created).
2462TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002463 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002464 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2465
solenberg7e63ef02015-11-20 00:19:43 -08002466 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002467
2468 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002469 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2470 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002471}
2472
solenberg2100c0b2017-03-01 11:29:29 -08002473// Test that receiving N unsignaled stream works (streams will be created), and
2474// that packets are forwarded to them all.
2475TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002476 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002477 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002478 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2479
solenberg2100c0b2017-03-01 11:29:29 -08002480 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002481 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002482 rtc::SetBE32(&packet[8], ssrc);
2483 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002484
solenberg2100c0b2017-03-01 11:29:29 -08002485 // Verify we have one new stream for each loop iteration.
2486 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2488 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002489 }
mflodman3d7db262016-04-29 00:57:13 -07002490
solenberg2100c0b2017-03-01 11:29:29 -08002491 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002492 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002493 rtc::SetBE32(&packet[8], ssrc);
2494 DeliverPacket(packet, sizeof(packet));
2495
solenbergebb349d2017-03-13 05:46:15 -07002496 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002497 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2498 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2499 }
2500
2501 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2502 constexpr uint32_t kAnotherSsrc = 667;
2503 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002504 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002505
2506 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002507 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002508 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002509 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002510 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2511 EXPECT_EQ(2, streams[i]->received_packets());
2512 }
2513 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2514 EXPECT_EQ(1, streams[i]->received_packets());
2515 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002516 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002517}
2518
solenberg2100c0b2017-03-01 11:29:29 -08002519// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002520// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002521TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002522 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002523 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002524 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2525
2526 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002527 const uint32_t signaled_ssrc = 1;
2528 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002529 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002530 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002531 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2532 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002533 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002534
2535 // Note that the first unknown SSRC cannot be 0, because we only support
2536 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002537 const uint32_t unsignaled_ssrc = 7011;
2538 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002539 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002540 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2541 packet, sizeof(packet)));
2542 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2543
2544 DeliverPacket(packet, sizeof(packet));
2545 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2546
2547 rtc::SetBE32(&packet[8], signaled_ssrc);
2548 DeliverPacket(packet, sizeof(packet));
2549 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2550 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002551}
2552
solenberg4904fb62017-02-17 12:01:14 -08002553// Two tests to verify that adding a receive stream with the same SSRC as a
2554// previously added unsignaled stream will only recreate underlying stream
2555// objects if the stream parameters have changed.
2556TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2557 EXPECT_TRUE(SetupChannel());
2558
2559 // Spawn unsignaled stream with SSRC=1.
2560 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2561 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2562 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2563 sizeof(kPcmuFrame)));
2564
2565 // Verify that the underlying stream object in Call is not recreated when a
2566 // stream with SSRC=1 is added.
2567 const auto& streams = call_.GetAudioReceiveStreams();
2568 EXPECT_EQ(1, streams.size());
2569 int audio_receive_stream_id = streams.front()->id();
2570 EXPECT_TRUE(AddRecvStream(1));
2571 EXPECT_EQ(1, streams.size());
2572 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2573}
2574
2575TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2576 EXPECT_TRUE(SetupChannel());
2577
2578 // Spawn unsignaled stream with SSRC=1.
2579 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2580 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2581 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2582 sizeof(kPcmuFrame)));
2583
2584 // Verify that the underlying stream object in Call *is* recreated when a
2585 // stream with SSRC=1 is added, and which has changed stream parameters.
2586 const auto& streams = call_.GetAudioReceiveStreams();
2587 EXPECT_EQ(1, streams.size());
2588 int audio_receive_stream_id = streams.front()->id();
2589 cricket::StreamParams stream_params;
2590 stream_params.ssrcs.push_back(1);
2591 stream_params.sync_label = "sync_label";
2592 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2593 EXPECT_EQ(1, streams.size());
2594 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2595}
2596
solenberg0a617e22015-10-20 15:49:38 -07002597// Test that we properly handle failures to add a receive stream.
2598TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002599 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002600 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002601 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002602}
2603
solenberg0a617e22015-10-20 15:49:38 -07002604// Test that we properly handle failures to add a send stream.
2605TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002606 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002607 voe_.set_fail_create_channel(true);
2608 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2609}
2610
solenberg1ac56142015-10-13 03:58:19 -07002611// Test that AddRecvStream creates new stream.
2612TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002613 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002614 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002615 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002616 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002617}
2618
2619// Test that after adding a recv stream, we do not decode more codecs than
2620// those previously passed into SetRecvCodecs.
2621TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002622 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002623 cricket::AudioRecvParameters parameters;
2624 parameters.codecs.push_back(kIsacCodec);
2625 parameters.codecs.push_back(kPcmuCodec);
2626 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002627 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002628 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2629 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2630 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631}
2632
2633// Test that we properly clean up any streams that were added, even if
2634// not explicitly removed.
2635TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002636 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002637 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002638 EXPECT_TRUE(AddRecvStream(1));
2639 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002640 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2641 delete channel_;
2642 channel_ = NULL;
2643 EXPECT_EQ(0, voe_.GetNumChannels());
2644}
2645
wu@webrtc.org78187522013-10-07 23:32:02 +00002646TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002648 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002649}
2650
2651TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002653 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002654 // Manually delete channel to simulate a failure.
2655 int channel = voe_.GetLastChannel();
2656 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2657 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002658 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002659 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002660 EXPECT_NE(channel, new_channel);
2661 // The last created channel is deleted too.
2662 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002663}
2664
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002665// Test the InsertDtmf on default send stream as caller.
2666TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002667 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002668}
2669
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002670// Test the InsertDtmf on default send stream as callee
2671TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002672 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002673}
2674
2675// Test the InsertDtmf on specified send stream as caller.
2676TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002677 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002678}
2679
2680// Test the InsertDtmf on specified send stream as callee.
2681TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002682 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002683}
2684
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002686 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002687 EXPECT_CALL(adm_,
2688 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2689 EXPECT_CALL(adm_,
2690 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2691 EXPECT_CALL(adm_,
2692 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002693
solenberg246b8172015-12-08 09:50:23 -08002694 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2695 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002696
solenberg246b8172015-12-08 09:50:23 -08002697 // Nothing set in AudioOptions, so everything should be as default.
2698 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002699 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002700 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002701 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2702 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703
2704 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002705 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2706 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002707 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002708 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002709
2710 // Turn echo cancellation back on, with settings, and make sure
2711 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002712 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2713 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002714 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002715 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002717 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2718 // control.
solenberg76377c52017-02-21 00:54:31 -08002719 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2720 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002721 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002722 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002723
2724 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002725 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2726 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002727 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2728 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2729 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002730 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002731
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002732 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002733 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2734 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002735 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002736 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002737
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002739 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2740 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2741 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002743 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002744 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002745
2746 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002747 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2748 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2749 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2750 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002751 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2752 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002753 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754
2755 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002756 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2757 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2758 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2759 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2760 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2762 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002763 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2764 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2765 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2766 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002767 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002768 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769
solenberg1ac56142015-10-13 03:58:19 -07002770 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2774 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2775 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2777 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002778 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002779}
2780
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002782 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002783 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002784 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002785 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002786 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002787 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002788 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002789 EXPECT_CALL(adm_,
2790 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2791 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2792 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
2793 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
2794 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002795
kwiberg686a8ef2016-02-26 03:00:35 -08002796 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002797 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002798 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002799 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002800 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002801 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802
2803 // Have to add a stream to make SetSend work.
2804 cricket::StreamParams stream1;
2805 stream1.ssrcs.push_back(1);
2806 channel1->AddSendStream(stream1);
2807 cricket::StreamParams stream2;
2808 stream2.ssrcs.push_back(2);
2809 channel2->AddSendStream(stream2);
2810
2811 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002812 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002813 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2814 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2815 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002816 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2817 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2818 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2819 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2820 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002821 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002822 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002823 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002824 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825
2826 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002827 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002828 parameters_options_no_ns.options.noise_suppression =
2829 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002830 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2831 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2832 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2833 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002835 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002836 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002837 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2838 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2839 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002840 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002841
2842 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002843 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002844 parameters_options_no_agc.options.auto_gain_control =
2845 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002846 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2847 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2848 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2849 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2850 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002851 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002852 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2853 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2854 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002855 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856
solenberg76377c52017-02-21 00:54:31 -08002857 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2858 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2859 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002862 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863
solenberg76377c52017-02-21 00:54:31 -08002864 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2865 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2866 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2867 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2868 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002869 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002870
solenberg76377c52017-02-21 00:54:31 -08002871 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2872 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2873 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002876 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2880 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002881 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002882 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002883 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002884 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002890 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002891 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2892 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2893 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002894 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895}
2896
wu@webrtc.orgde305012013-10-31 15:40:38 +00002897// This test verifies DSCP settings are properly applied on voice media channel.
2898TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002899 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002900 cricket::FakeNetworkInterface network_interface;
2901 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002902 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002903
solenberg059fb442016-10-26 05:12:24 -07002904 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
2905 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
2906
solenbergbc37fc82016-04-04 09:54:44 -07002907 channel.reset(
2908 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002909 channel->SetInterface(&network_interface);
2910 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2911 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2912
2913 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002914 channel.reset(
2915 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002916 channel->SetInterface(&network_interface);
2917 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2918
2919 // Verify that setting the option to false resets the
2920 // DiffServCodePoint.
2921 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002922 channel.reset(
2923 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002924 channel->SetInterface(&network_interface);
2925 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2926 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2927
2928 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002929}
2930
solenberg1ac56142015-10-13 03:58:19 -07002931TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002932 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933 cricket::WebRtcVoiceMediaChannel* media_channel =
2934 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002935 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002936 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002937 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002938 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2939 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2940 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002941 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002942 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002943}
2944
solenberg1ac56142015-10-13 03:58:19 -07002945TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002946 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002948 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2949 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2950 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002951 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002952 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002953 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2954 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002955 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002956 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002957 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002958 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959}
2960
solenberg4bac9c52015-10-09 02:32:53 -07002961TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002962 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002963 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002964 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002965 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002966 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002967 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2968 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2969 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002970}
2971
solenberg2100c0b2017-03-01 11:29:29 -08002972TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002973 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002974
2975 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002976 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002977 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2978
2979 // Should remember the volume "2" which will be set on new unsignaled streams,
2980 // and also set the gain to 2 on existing unsignaled streams.
2981 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2982 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2983
2984 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2985 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2986 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2987 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2988 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2989 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2990
2991 // Setting gain with SSRC=0 should affect all unsignaled streams.
2992 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002993 if (kMaxUnsignaledRecvStreams > 1) {
2994 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
2995 }
solenberg2100c0b2017-03-01 11:29:29 -08002996 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
2997
2998 // Setting gain on an individual stream affects only that.
2999 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003000 if (kMaxUnsignaledRecvStreams > 1) {
3001 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3002 }
solenberg2100c0b2017-03-01 11:29:29 -08003003 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004}
3005
pbos8fc7fa72015-07-15 08:02:58 -07003006TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003007 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003008 const std::string kSyncLabel = "AvSyncLabel";
3009
solenbergff976312016-03-30 23:28:51 -07003010 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003011 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3012 sp.sync_label = kSyncLabel;
3013 // Creating two channels to make sure that sync label is set properly for both
3014 // the default voice channel and following ones.
3015 EXPECT_TRUE(channel_->AddRecvStream(sp));
3016 sp.ssrcs[0] += 1;
3017 EXPECT_TRUE(channel_->AddRecvStream(sp));
3018
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003019 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003020 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003021 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003022 << "SyncGroup should be set based on sync_label";
3023 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003024 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003025 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003026}
3027
solenberg3a941542015-11-16 07:34:50 -08003028// TODO(solenberg): Remove, once recv streams are configured through Call.
3029// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003030TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003031 // Test that setting the header extensions results in the expected state
3032 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003033 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003034 ssrcs.push_back(223);
3035 ssrcs.push_back(224);
3036
solenbergff976312016-03-30 23:28:51 -07003037 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003038 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003039 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003040 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003041 cricket::StreamParams::CreateLegacy(ssrc)));
3042 }
3043
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003044 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003045 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003046 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003047 EXPECT_NE(nullptr, s);
3048 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3049 }
3050
3051 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003052 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003053 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003054 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003055 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003056 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003057 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003058 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003059 EXPECT_NE(nullptr, s);
3060 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003061 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3062 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003063 for (const auto& s_ext : s_exts) {
3064 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003065 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003066 }
3067 }
3068 }
3069 }
3070
3071 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003072 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003073 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003074 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003075 EXPECT_NE(nullptr, s);
3076 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3077 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003078}
3079
3080TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3081 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003082 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003083 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003084 static const unsigned char kRtcp[] = {
3085 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3086 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3088 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3089 };
jbaucheec21bd2016-03-20 06:15:43 -07003090 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091
solenbergff976312016-03-30 23:28:51 -07003092 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093 cricket::WebRtcVoiceMediaChannel* media_channel =
3094 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003095 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003096 EXPECT_TRUE(media_channel->AddRecvStream(
3097 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3098
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003099 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003101 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102 EXPECT_EQ(0, s->received_packets());
3103 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3104 EXPECT_EQ(1, s->received_packets());
3105 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3106 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107}
Minyue2013aec2015-05-13 14:14:42 +02003108
solenberg0a617e22015-10-20 15:49:38 -07003109// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003110// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003111TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003112 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003113 EXPECT_TRUE(AddRecvStream(kSsrcY));
3114 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003115 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003116 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3117 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3118 EXPECT_TRUE(AddRecvStream(kSsrcW));
3119 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003120}
3121
solenberg7602aab2016-11-14 11:30:07 -08003122TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3123 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003124 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003125 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003126 cricket::StreamParams::CreateLegacy(kSsrcY)));
3127 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3128 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3129 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003130 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003131 cricket::StreamParams::CreateLegacy(kSsrcW)));
3132 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3133 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003134}
stefan658910c2015-09-03 05:48:32 -07003135
deadbeef884f5852016-01-15 09:20:04 -08003136TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003137 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003138 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3139 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003140
3141 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003142 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3143 EXPECT_TRUE(AddRecvStream(kSsrcX));
3144 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003145
3146 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003147 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3148 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003149
3150 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003151 channel_->SetRawAudioSink(kSsrcX, nullptr);
3152 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003153}
3154
solenberg2100c0b2017-03-01 11:29:29 -08003155TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003156 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003157 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3158 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003159 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3160 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003161
3162 // Should be able to set a default sink even when no stream exists.
3163 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3164
solenberg2100c0b2017-03-01 11:29:29 -08003165 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3166 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003167 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003168 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003169
3170 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003171 channel_->SetRawAudioSink(kSsrc0, nullptr);
3172 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003173
3174 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003175 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3176 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003177
3178 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003179 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003180 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003181 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3182
3183 // Spawn another unsignaled stream - it should be assigned the default sink
3184 // and the previous unsignaled stream should lose it.
3185 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3186 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3187 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3188 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003189 if (kMaxUnsignaledRecvStreams > 1) {
3190 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3191 }
solenberg2100c0b2017-03-01 11:29:29 -08003192 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3193
3194 // Reset the default sink - the second unsignaled stream should lose it.
3195 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003196 if (kMaxUnsignaledRecvStreams > 1) {
3197 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3198 }
solenberg2100c0b2017-03-01 11:29:29 -08003199 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3200
3201 // Try setting the default sink while two streams exists.
3202 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003203 if (kMaxUnsignaledRecvStreams > 1) {
3204 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3205 }
solenberg2100c0b2017-03-01 11:29:29 -08003206 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3207
3208 // Try setting the sink for the first unsignaled stream using its known SSRC.
3209 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003210 if (kMaxUnsignaledRecvStreams > 1) {
3211 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3212 }
solenberg2100c0b2017-03-01 11:29:29 -08003213 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003214 if (kMaxUnsignaledRecvStreams > 1) {
3215 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3216 }
deadbeef884f5852016-01-15 09:20:04 -08003217}
3218
skvlad7a43d252016-03-22 15:32:27 -07003219// Test that, just like the video channel, the voice channel communicates the
3220// network state to the call.
3221TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003222 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003223
3224 EXPECT_EQ(webrtc::kNetworkUp,
3225 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3226 EXPECT_EQ(webrtc::kNetworkUp,
3227 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3228
3229 channel_->OnReadyToSend(false);
3230 EXPECT_EQ(webrtc::kNetworkDown,
3231 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3232 EXPECT_EQ(webrtc::kNetworkUp,
3233 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3234
3235 channel_->OnReadyToSend(true);
3236 EXPECT_EQ(webrtc::kNetworkUp,
3237 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3238 EXPECT_EQ(webrtc::kNetworkUp,
3239 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3240}
3241
aleloi18e0b672016-10-04 02:45:47 -07003242// Test that playout is still started after changing parameters
3243TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3244 SetupRecvStream();
3245 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003246 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003247
3248 // Changing RTP header extensions will recreate the AudioReceiveStream.
3249 cricket::AudioRecvParameters parameters;
3250 parameters.extensions.push_back(
3251 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3252 channel_->SetRecvParameters(parameters);
3253
solenberg2100c0b2017-03-01 11:29:29 -08003254 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003255}
3256
stefan658910c2015-09-03 05:48:32 -07003257// Tests that the library initializes and shuts down properly.
3258TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003259 // If the VoiceEngine wants to gather available codecs early, that's fine but
3260 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003261 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003262 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3263 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003264 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003265 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003266 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003267 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3268 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003269 EXPECT_TRUE(channel != nullptr);
3270 delete channel;
solenbergff976312016-03-30 23:28:51 -07003271}
stefan658910c2015-09-03 05:48:32 -07003272
solenbergff976312016-03-30 23:28:51 -07003273// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003274TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3275 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3276 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3277 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003278 // Return 100ms just in case this function gets called. If we don't,
3279 // we could enter a tight loop since the mock would return 0.
3280 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003281 {
ossuc54071d2016-08-17 02:45:41 -07003282 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003283 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3284 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003285 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003286 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003287 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003288 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3289 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3290 EXPECT_TRUE(channel != nullptr);
3291 delete channel;
3292 }
stefan658910c2015-09-03 05:48:32 -07003293}
3294
ossu20a4b3f2017-04-27 02:08:52 -07003295// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3296TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003297 // TODO(ossu): Why are the payload types of codecs with non-static payload
3298 // type assignments checked here? It shouldn't really matter.
3299 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003300 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3301 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003302 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003303 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3304 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3305 (clockrate == 0 || codec.clockrate == clockrate);
3306 };
3307 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003308 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003309 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003310 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003311 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003312 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003313 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003314 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003315 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003316 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003317 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003318 EXPECT_EQ(126, codec.id);
3319 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3320 // Remove these checks once both send and receive side assigns payload types
3321 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003322 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003323 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003324 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003325 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003326 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003327 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003328 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003329 EXPECT_EQ(111, codec.id);
3330 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3331 EXPECT_EQ("10", codec.params.find("minptime")->second);
3332 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3333 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003334 }
3335 }
stefan658910c2015-09-03 05:48:32 -07003336}
3337
3338// Tests that VoE supports at least 32 channels
3339TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003340 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003341 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3342 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003343 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003344 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003345 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003346
3347 cricket::VoiceMediaChannel* channels[32];
3348 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003349 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003350 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3351 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003352 if (!channel)
3353 break;
stefan658910c2015-09-03 05:48:32 -07003354 channels[num_channels++] = channel;
3355 }
3356
tfarina5237aaf2015-11-10 23:44:30 -08003357 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003358 EXPECT_EQ(expected, num_channels);
3359
3360 while (num_channels > 0) {
3361 delete channels[--num_channels];
3362 }
stefan658910c2015-09-03 05:48:32 -07003363}
3364
3365// Test that we set our preferred codecs properly.
3366TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003367 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3368 // - Check that our builtin codecs are usable by Channel.
3369 // - The codecs provided by the engine is usable by Channel.
3370 // It does not check that the codecs in the RecvParameters are actually
3371 // what we sent in - though it's probably reasonable to expect so, if
3372 // SetRecvParameters returns true.
3373 // I think it will become clear once audio decoder injection is completed.
3374 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003375 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3376 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003377 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003378 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003379 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003380 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3381 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003382 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003383 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003384 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003385}
ossu9def8002017-02-09 05:14:32 -08003386
3387TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3388 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003389 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3390 {48000, 2, 16000, 10000, 20000}};
3391 spec1.info.allow_comfort_noise = false;
3392 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003393 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003394 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3395 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003396 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003397 specs.push_back(webrtc::AudioCodecSpec{
3398 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3399 {16000, 1, 13300}});
3400 specs.push_back(
3401 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3402 specs.push_back(
3403 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003404
ossueb1fde42017-05-02 06:46:30 -07003405 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3406 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3407 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003408 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003409 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003410 .WillOnce(Return(specs));
3411
ossueb1fde42017-05-02 06:46:30 -07003412 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
3413 mock_decoder_factory, nullptr);
ossu9def8002017-02-09 05:14:32 -08003414 auto codecs = engine.recv_codecs();
3415 EXPECT_EQ(11, codecs.size());
3416
3417 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3418 // check the actual values safely, to provide better test results.
3419 auto get_codec =
3420 [&codecs](size_t index) -> const cricket::AudioCodec& {
3421 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3422 if (codecs.size() > index)
3423 return codecs[index];
3424 return missing_codec;
3425 };
3426
3427 // Ensure the general codecs are generated first and in order.
3428 for (size_t i = 0; i != specs.size(); ++i) {
3429 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3430 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3431 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3432 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3433 }
3434
3435 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003436 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003437 auto find_codec =
3438 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3439 for (size_t i = 0; i != codecs.size(); ++i) {
3440 const cricket::AudioCodec& codec = codecs[i];
3441 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3442 codec.clockrate == format.clockrate_hz &&
3443 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003444 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003445 }
3446 }
3447 return -1;
3448 };
3449
3450 // Ensure all supplementary codecs are generated last. Their internal ordering
3451 // is not important.
3452 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3453 const int num_specs = static_cast<int>(specs.size());
3454 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3455 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3456 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3457 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3458 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3459 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3460 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3461}