blob: 4e20dfc16a23f6f576bbbfce6d8008230ebee935 [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>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010039using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010046using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020047
solenberg418b7d32017-06-13 00:38:27 -070048constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070049
deadbeef67cf2c12016-04-13 10:07:16 -070050const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
51const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070052const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
54const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
56const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020057const cricket::AudioCodec kTelephoneEventCodec1(106,
58 "telephone-event",
59 8000,
60 0,
61 1);
62const cricket::AudioCodec kTelephoneEventCodec2(107,
63 "telephone-event",
64 32000,
65 0,
66 1);
solenberg2779bab2016-11-17 04:45:19 -080067
solenberg2100c0b2017-03-01 11:29:29 -080068const uint32_t kSsrc0 = 0;
69const uint32_t kSsrc1 = 1;
70const uint32_t kSsrcX = 0x99;
71const uint32_t kSsrcY = 0x17;
72const uint32_t kSsrcZ = 0x42;
73const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020074const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075
solenberg971cab02016-06-14 10:02:41 -070076constexpr int kRtpHistoryMs = 5000;
77
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010078constexpr webrtc::GainControl::Mode kDefaultAgcMode =
79#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
80 webrtc::GainControl::kFixedDigital;
81#else
82 webrtc::GainControl::kAdaptiveAnalog;
83#endif
84
85constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
86 webrtc::NoiseSuppression::kHigh;
87
solenberg9a5f032222017-03-15 06:14:12 -070088void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
89 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010090
91 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010092 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010093 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010094 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070095#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020096 EXPECT_CALL(
97 *adm, SetPlayoutDevice(
98 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
99 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
100 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700101#else
102 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
103#endif // #if defined(WEBRTC_WIN)
104 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
105 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
106 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100107#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200108 EXPECT_CALL(
109 *adm, SetRecordingDevice(
110 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
111 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
112 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113#else
114 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
115#endif // #if defined(WEBRTC_WIN)
116 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
118 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700119 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100122
123 // Teardown.
124 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
125 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
127 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200128 EXPECT_CALL(*adm, Release())
129 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100130 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700131}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200132} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133
solenbergff976312016-03-30 23:28:51 -0700134// Tests that our stub library "works".
135TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700136 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700137 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700138 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
139 new rtc::RefCountedObject<
140 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700141 webrtc::AudioProcessing::Config apm_config;
142 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
143 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700144 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700146 {
ossuc54071d2016-08-17 02:45:41 -0700147 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700148 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100149 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700150 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700151 }
solenbergff976312016-03-30 23:28:51 -0700152}
153
deadbeef884f5852016-01-15 09:20:04 -0800154class FakeAudioSink : public webrtc::AudioSinkInterface {
155 public:
156 void OnData(const Data& audio) override {}
157};
158
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800159class FakeAudioSource : public cricket::AudioSource {
160 void SetSink(Sink* sink) override {}
161};
162
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163class WebRtcVoiceEngineTestFake : public testing::Test {
164 public:
stefanba4c0e42016-02-04 04:12:24 -0800165 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
166
167 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700168 : apm_(new rtc::RefCountedObject<
169 StrictMock<webrtc::test::MockAudioProcessing>>()),
170 apm_gc_(*apm_->gain_control()),
171 apm_ec_(*apm_->echo_cancellation()),
172 apm_ns_(*apm_->noise_suppression()),
173 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100174 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700175 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800176 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700177 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800178 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700179 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
180 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700182 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800183 // Default Options.
184 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
185 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100186 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
187 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800188 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100189 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
190 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800191 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
192 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800193 // Init does not overwrite default AGC config.
194 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
195 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
196 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800197 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
198 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700199 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800200 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700201 // factories. Those tests should probably be moved elsewhere.
202 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
203 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100204 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100205 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700206 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200207 send_parameters_.codecs.push_back(kPcmuCodec);
208 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100209
solenberg76377c52017-02-21 00:54:31 -0800210 // Default Options.
211 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
solenberg8189b022016-06-14 12:13:00 -0700213
solenbergff976312016-03-30 23:28:51 -0700214 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700215 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700216 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
217 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200218 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000219 }
solenberg8189b022016-06-14 12:13:00 -0700220
solenbergff976312016-03-30 23:28:51 -0700221 bool SetupRecvStream() {
222 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700223 return false;
224 }
solenberg2100c0b2017-03-01 11:29:29 -0800225 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700226 }
solenberg8189b022016-06-14 12:13:00 -0700227
solenbergff976312016-03-30 23:28:51 -0700228 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200229 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
230 }
231
232 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700233 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000234 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 }
Florent Castellidacec712018-05-24 16:24:21 +0200236 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800237 return false;
238 }
peaha9cc40b2017-06-29 08:32:09 -0700239 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800240 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 }
solenberg8189b022016-06-14 12:13:00 -0700242
243 bool AddRecvStream(uint32_t ssrc) {
244 EXPECT_TRUE(channel_);
245 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
246 }
247
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000248 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700249 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700250 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800251 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
252 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700253 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800254 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000255 }
solenberg8189b022016-06-14 12:13:00 -0700256
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700258 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000259 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 }
solenberg8189b022016-06-14 12:13:00 -0700261
Yves Gerey665174f2018-06-19 15:03:05 +0200262 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100264 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
265 const auto* send_stream = call_.GetAudioSendStream(ssrc);
266 EXPECT_TRUE(send_stream);
267 return *send_stream;
268 }
269
deadbeef884f5852016-01-15 09:20:04 -0800270 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
271 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
272 EXPECT_TRUE(recv_stream);
273 return *recv_stream;
274 }
275
solenberg3a941542015-11-16 07:34:50 -0800276 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800277 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800278 }
279
solenberg7add0582015-11-20 09:59:34 -0800280 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800281 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800282 }
283
solenberg059fb442016-10-26 05:12:24 -0700284 void SetSend(bool enable) {
285 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700286 if (enable) {
287 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
288 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
289 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700290 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700291 }
solenberg059fb442016-10-26 05:12:24 -0700292 channel_->SetSend(enable);
293 }
294
295 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700296 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700297 ASSERT_TRUE(channel_);
298 EXPECT_TRUE(channel_->SetSendParameters(params));
299 }
300
Yves Gerey665174f2018-06-19 15:03:05 +0200301 void SetAudioSend(uint32_t ssrc,
302 bool enable,
303 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700304 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700305 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700306 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700307 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700308 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700309 }
310 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700311 }
312
Yves Gerey665174f2018-06-19 15:03:05 +0200313 void TestInsertDtmf(uint32_t ssrc,
314 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800315 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700316 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700318 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000319 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200320 EXPECT_TRUE(
321 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000323
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700325 SetSendParameters(send_parameters_);
326 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800328 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800329 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700330 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000332
333 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700334 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800335 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200336 EXPECT_TRUE(
337 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000338 }
339
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800341 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100343 // Test send.
344 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800345 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100346 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800347 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800348 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800349 EXPECT_EQ(codec.id, telephone_event.payload_type);
350 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100351 EXPECT_EQ(2, telephone_event.event_code);
352 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353 }
354
355 // Test that send bandwidth is set correctly.
356 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000357 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
358 // |expected_result| is the expected result from SetMaxSendBandwidth().
359 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700360 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
361 int max_bitrate,
362 bool expected_result,
363 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200364 cricket::AudioSendParameters parameters;
365 parameters.codecs.push_back(codec);
366 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700367 if (expected_result) {
368 SetSendParameters(parameters);
369 } else {
370 EXPECT_FALSE(channel_->SetSendParameters(parameters));
371 }
solenberg2100c0b2017-03-01 11:29:29 -0800372 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 }
374
skvlade0d46372016-04-07 22:59:22 -0700375 // Sets the per-stream maximum bitrate limit for the specified SSRC.
376 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700377 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700378 EXPECT_EQ(1UL, parameters.encodings.size());
379
Oskar Sundbom78807582017-11-16 11:09:55 +0100380 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800381 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700382 }
383
solenberg059fb442016-10-26 05:12:24 -0700384 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700385 cricket::AudioSendParameters send_parameters;
386 send_parameters.codecs.push_back(codec);
387 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700388 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700389 }
390
ossu20a4b3f2017-04-27 02:08:52 -0700391 void CheckSendCodecBitrate(int32_t ssrc,
392 const char expected_name[],
393 int expected_bitrate) {
394 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
395 EXPECT_EQ(expected_name, spec->format.name);
396 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700397 }
398
Danil Chapovalov00c71832018-06-15 15:58:38 +0200399 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700400 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700401 }
402
Danil Chapovalov00c71832018-06-15 15:58:38 +0200403 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
404 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700405 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
406 }
407
skvlade0d46372016-04-07 22:59:22 -0700408 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
409 int global_max,
410 int stream_max,
411 bool expected_result,
412 int expected_codec_bitrate) {
413 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800414 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700415
416 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700417 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800418 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700419
420 // Verify that reading back the parameters gives results
421 // consistent with the Set() result.
422 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800423 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700424 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
425 EXPECT_EQ(expected_result ? stream_max : -1,
426 resulting_parameters.encodings[0].max_bitrate_bps);
427
428 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800429 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700430 }
431
stefan13f1a0a2016-11-30 07:22:58 -0800432 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
433 int expected_min_bitrate_bps,
434 const char* start_bitrate_kbps,
435 int expected_start_bitrate_bps,
436 const char* max_bitrate_kbps,
437 int expected_max_bitrate_bps) {
438 EXPECT_TRUE(SetupSendStream());
439 auto& codecs = send_parameters_.codecs;
440 codecs.clear();
441 codecs.push_back(kOpusCodec);
442 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
443 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
444 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100445 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
446 SetSdpBitrateParameters(
447 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
448 expected_min_bitrate_bps),
449 Field(&BitrateConstraints::start_bitrate_bps,
450 expected_start_bitrate_bps),
451 Field(&BitrateConstraints::max_bitrate_bps,
452 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800453
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100454 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800455 }
456
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000457 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700458 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000459
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000460 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
463 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700464 send_parameters_.extensions.push_back(
465 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000468
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000469 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200470 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700471 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800472 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000473
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000474 // Ensure extension is set properly.
475 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700476 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700477 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800478 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
479 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
480 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000481
solenberg7add0582015-11-20 09:59:34 -0800482 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200483 EXPECT_TRUE(
484 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
486 call_.GetAudioSendStream(kSsrcY));
487 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
488 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
489 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
491 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200492 send_parameters_.codecs.push_back(kPcmuCodec);
493 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700494 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
496 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000497 }
498
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000499 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700500 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000501
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000502 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
505 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700506 recv_parameters_.extensions.push_back(
507 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000510
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000511 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800512 recv_parameters_.extensions.clear();
513 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000515
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000516 // Ensure extension is set properly.
517 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700518 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800519 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
521 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
522 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000523
solenberg7add0582015-11-20 09:59:34 -0800524 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_TRUE(AddRecvStream(kSsrcY));
526 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
527 call_.GetAudioReceiveStream(kSsrcY));
528 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
529 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
530 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000531
532 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800533 recv_parameters_.extensions.clear();
534 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800535 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
536 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000537 }
538
solenberg85a04962015-10-27 03:35:21 -0700539 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
540 webrtc::AudioSendStream::Stats stats;
541 stats.local_ssrc = 12;
542 stats.bytes_sent = 345;
543 stats.packets_sent = 678;
544 stats.packets_lost = 9012;
545 stats.fraction_lost = 34.56f;
546 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100547 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700548 stats.ext_seqnum = 789;
549 stats.jitter_ms = 12;
550 stats.rtt_ms = 345;
551 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100552 stats.apm_statistics.delay_median_ms = 234;
553 stats.apm_statistics.delay_standard_deviation_ms = 567;
554 stats.apm_statistics.echo_return_loss = 890;
555 stats.apm_statistics.echo_return_loss_enhancement = 1234;
556 stats.apm_statistics.residual_echo_likelihood = 0.432f;
557 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100558 stats.ana_statistics.bitrate_action_counter = 321;
559 stats.ana_statistics.channel_action_counter = 432;
560 stats.ana_statistics.dtx_action_counter = 543;
561 stats.ana_statistics.fec_action_counter = 654;
562 stats.ana_statistics.frame_length_increase_counter = 765;
563 stats.ana_statistics.frame_length_decrease_counter = 876;
564 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700565 stats.typing_noise_detected = true;
566 return stats;
567 }
568 void SetAudioSendStreamStats() {
569 for (auto* s : call_.GetAudioSendStreams()) {
570 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200571 }
solenberg85a04962015-10-27 03:35:21 -0700572 }
solenberg566ef242015-11-06 15:34:49 -0800573 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
574 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700575 const auto stats = GetAudioSendStreamStats();
576 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
577 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
578 EXPECT_EQ(info.packets_sent, stats.packets_sent);
579 EXPECT_EQ(info.packets_lost, stats.packets_lost);
580 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
581 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800582 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700583 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
584 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
585 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
586 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100587 EXPECT_EQ(info.apm_statistics.delay_median_ms,
588 stats.apm_statistics.delay_median_ms);
589 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
590 stats.apm_statistics.delay_standard_deviation_ms);
591 EXPECT_EQ(info.apm_statistics.echo_return_loss,
592 stats.apm_statistics.echo_return_loss);
593 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
594 stats.apm_statistics.echo_return_loss_enhancement);
595 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
596 stats.apm_statistics.residual_echo_likelihood);
597 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
598 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700599 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
600 stats.ana_statistics.bitrate_action_counter);
601 EXPECT_EQ(info.ana_statistics.channel_action_counter,
602 stats.ana_statistics.channel_action_counter);
603 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
604 stats.ana_statistics.dtx_action_counter);
605 EXPECT_EQ(info.ana_statistics.fec_action_counter,
606 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700607 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
608 stats.ana_statistics.frame_length_increase_counter);
609 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
610 stats.ana_statistics.frame_length_decrease_counter);
611 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
612 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800613 EXPECT_EQ(info.typing_noise_detected,
614 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700615 }
616
617 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
618 webrtc::AudioReceiveStream::Stats stats;
619 stats.remote_ssrc = 123;
620 stats.bytes_rcvd = 456;
621 stats.packets_rcvd = 768;
622 stats.packets_lost = 101;
623 stats.fraction_lost = 23.45f;
624 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100625 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700626 stats.ext_seqnum = 678;
627 stats.jitter_ms = 901;
628 stats.jitter_buffer_ms = 234;
629 stats.jitter_buffer_preferred_ms = 567;
630 stats.delay_estimate_ms = 890;
631 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700632 stats.total_samples_received = 5678901;
633 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200634 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200635 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700636 stats.expand_rate = 5.67f;
637 stats.speech_expand_rate = 8.90f;
638 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200639 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700640 stats.accelerate_rate = 4.56f;
641 stats.preemptive_expand_rate = 7.89f;
642 stats.decoding_calls_to_silence_generator = 12;
643 stats.decoding_calls_to_neteq = 345;
644 stats.decoding_normal = 67890;
645 stats.decoding_plc = 1234;
646 stats.decoding_cng = 5678;
647 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700648 stats.decoding_muted_output = 3456;
649 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200650 return stats;
651 }
652 void SetAudioReceiveStreamStats() {
653 for (auto* s : call_.GetAudioReceiveStreams()) {
654 s->SetStats(GetAudioReceiveStreamStats());
655 }
656 }
657 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700658 const auto stats = GetAudioReceiveStreamStats();
659 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
660 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200661 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
662 stats.packets_rcvd);
663 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
664 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700665 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
666 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800667 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200668 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
669 stats.ext_seqnum);
670 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
671 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
672 stats.jitter_buffer_ms);
673 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700674 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200675 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
676 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700677 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700678 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
679 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200680 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200681 EXPECT_EQ(info.jitter_buffer_delay_seconds,
682 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700683 EXPECT_EQ(info.expand_rate, stats.expand_rate);
684 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
685 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200686 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700687 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
688 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200689 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700690 stats.decoding_calls_to_silence_generator);
691 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
692 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
693 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
694 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
695 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700696 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700697 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200698 }
hbos1acfbd22016-11-17 23:43:29 -0800699 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
700 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
701 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
702 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
703 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
704 codec.ToCodecParameters());
705 }
706 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
707 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
708 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
709 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
710 codec.ToCodecParameters());
711 }
712 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200713
peah8271d042016-11-22 07:24:52 -0800714 bool IsHighPassFilterEnabled() {
715 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
716 }
717
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700719 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700720 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800721 webrtc::test::MockGainControl& apm_gc_;
722 webrtc::test::MockEchoCancellation& apm_ec_;
723 webrtc::test::MockNoiseSuppression& apm_ns_;
724 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200725 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700726 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700727 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200728 cricket::AudioSendParameters send_parameters_;
729 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800730 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700731 webrtc::AudioProcessing::Config apm_config_;
732
stefanba4c0e42016-02-04 04:12:24 -0800733 private:
734 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735};
736
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737// Tests that we can create and destroy a channel.
738TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700739 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740}
741
solenberg31fec402016-05-06 02:13:12 -0700742// Test that we can add a send stream and that it has the correct defaults.
743TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
744 EXPECT_TRUE(SetupChannel());
745 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800746 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
747 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
748 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700749 EXPECT_EQ("", config.rtp.c_name);
750 EXPECT_EQ(0u, config.rtp.extensions.size());
751 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
752 config.send_transport);
753}
754
755// Test that we can add a receive stream and that it has the correct defaults.
756TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
757 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800758 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700759 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800760 GetRecvStreamConfig(kSsrcX);
761 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700762 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
763 EXPECT_FALSE(config.rtp.transport_cc);
764 EXPECT_EQ(0u, config.rtp.extensions.size());
765 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
766 config.rtcp_send_transport);
767 EXPECT_EQ("", config.sync_group);
768}
769
stefanba4c0e42016-02-04 04:12:24 -0800770TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700771 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800772 bool opus_found = false;
773 for (cricket::AudioCodec codec : codecs) {
774 if (codec.name == "opus") {
775 EXPECT_TRUE(HasTransportCc(codec));
776 opus_found = true;
777 }
778 }
779 EXPECT_TRUE(opus_found);
780}
781
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782// Test that we set our inbound codecs properly, including changing PT.
783TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700784 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 cricket::AudioRecvParameters parameters;
786 parameters.codecs.push_back(kIsacCodec);
787 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800788 parameters.codecs.push_back(kTelephoneEventCodec1);
789 parameters.codecs.push_back(kTelephoneEventCodec2);
790 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 parameters.codecs[2].id = 126;
792 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800793 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700794 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
795 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
796 {{0, {"PCMU", 8000, 1}},
797 {106, {"ISAC", 16000, 1}},
798 {126, {"telephone-event", 8000, 1}},
799 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800}
801
802// Test that we fail to set an unknown inbound codec.
803TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700804 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200805 cricket::AudioRecvParameters parameters;
806 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700807 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200808 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that we fail if we have duplicate types in the inbound list.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kCn16000Codec);
817 parameters.codecs[1].id = kIsacCodec.id;
818 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that we can decode OPUS without stereo parameters.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700823 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 cricket::AudioRecvParameters parameters;
825 parameters.codecs.push_back(kIsacCodec);
826 parameters.codecs.push_back(kPcmuCodec);
827 parameters.codecs.push_back(kOpusCodec);
828 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800829 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700830 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
831 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
832 {{0, {"PCMU", 8000, 1}},
833 {103, {"ISAC", 16000, 1}},
834 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835}
836
837// Test that we can decode OPUS with stereo = 0.
838TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700839 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 cricket::AudioRecvParameters parameters;
841 parameters.codecs.push_back(kIsacCodec);
842 parameters.codecs.push_back(kPcmuCodec);
843 parameters.codecs.push_back(kOpusCodec);
844 parameters.codecs[2].params["stereo"] = "0";
845 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800846 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700847 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
848 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
849 {{0, {"PCMU", 8000, 1}},
850 {103, {"ISAC", 16000, 1}},
851 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852}
853
854// Test that we can decode OPUS with stereo = 1.
855TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700856 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 cricket::AudioRecvParameters parameters;
858 parameters.codecs.push_back(kIsacCodec);
859 parameters.codecs.push_back(kPcmuCodec);
860 parameters.codecs.push_back(kOpusCodec);
861 parameters.codecs[2].params["stereo"] = "1";
862 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800863 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700864 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
865 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
866 {{0, {"PCMU", 8000, 1}},
867 {103, {"ISAC", 16000, 1}},
868 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869}
870
871// Test that changes to recv codecs are applied to all streams.
872TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700873 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200874 cricket::AudioRecvParameters parameters;
875 parameters.codecs.push_back(kIsacCodec);
876 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800877 parameters.codecs.push_back(kTelephoneEventCodec1);
878 parameters.codecs.push_back(kTelephoneEventCodec2);
879 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200880 parameters.codecs[2].id = 126;
881 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700882 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
883 EXPECT_TRUE(AddRecvStream(ssrc));
884 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
885 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
886 {{0, {"PCMU", 8000, 1}},
887 {106, {"ISAC", 16000, 1}},
888 {126, {"telephone-event", 8000, 1}},
889 {107, {"telephone-event", 32000, 1}}})));
890 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891}
892
893TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700894 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200895 cricket::AudioRecvParameters parameters;
896 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800897 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
solenberg2100c0b2017-03-01 11:29:29 -0800900 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200901 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800902 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903}
904
905// Test that we can apply the same set of codecs again while playing.
906TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700907 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 cricket::AudioRecvParameters parameters;
909 parameters.codecs.push_back(kIsacCodec);
910 parameters.codecs.push_back(kCn16000Codec);
911 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700912 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
deadbeefcb383672017-04-26 16:28:42 -0700915 // Remapping a payload type to a different codec should fail.
916 parameters.codecs[0] = kOpusCodec;
917 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800919 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
922// Test that we can add a codec while playing.
923TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700924 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200925 cricket::AudioRecvParameters parameters;
926 parameters.codecs.push_back(kIsacCodec);
927 parameters.codecs.push_back(kCn16000Codec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700929 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 parameters.codecs.push_back(kOpusCodec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800933 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934}
935
deadbeefcb383672017-04-26 16:28:42 -0700936// Test that we accept adding the same codec with a different payload type.
937// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
938TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
939 EXPECT_TRUE(SetupRecvStream());
940 cricket::AudioRecvParameters parameters;
941 parameters.codecs.push_back(kIsacCodec);
942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
943
944 ++parameters.codecs[0].id;
945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
946}
947
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700949 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951 // Test that when autobw is enabled, bitrate is kept as the default
952 // value. autobw is enabled for the following tests because the target
953 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
955 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700956 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
958 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960
ossu20a4b3f2017-04-27 02:08:52 -0700961 // opus, default bitrate == 32000 in mono.
962 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000965TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700966 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700969 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
970 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700971 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700974 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
975 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
976 // Rates above the max (510000) should be capped.
977 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978}
979
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000982
983 // Test that we can only set a maximum bitrate for a fixed-rate codec
984 // if it's bigger than the fixed rate.
985
986 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700987 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
988 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
989 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
991 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000994}
995
996TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700997 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200998 const int kDesiredBitrate = 128000;
999 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001000 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001001 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001002 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001003
Yves Gerey665174f2018-06-19 15:03:05 +02001004 EXPECT_TRUE(
1005 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001006
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001008}
1009
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010// Test that bitrate cannot be set for CBR codecs.
1011// Bitrate is ignored if it is higher than the fixed bitrate.
1012// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001013TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001014 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015
1016 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001017 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001018 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001019
1020 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001021 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001022 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001023
1024 send_parameters_.max_bandwidth_bps = 128;
1025 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001026 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027}
1028
skvlade0d46372016-04-07 22:59:22 -07001029// Test that the per-stream bitrate limit and the global
1030// bitrate limit both apply.
1031TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1032 EXPECT_TRUE(SetupSendStream());
1033
ossu20a4b3f2017-04-27 02:08:52 -07001034 // opus, default bitrate == 32000.
1035 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001036 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1037 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1038 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1039
1040 // CBR codecs allow both maximums to exceed the bitrate.
1041 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1042 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1043 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1044 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1045
1046 // CBR codecs don't allow per stream maximums to be too low.
1047 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1049}
1050
1051// Test that an attempt to set RtpParameters for a stream that does not exist
1052// fails.
1053TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1054 EXPECT_TRUE(SetupChannel());
1055 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001056 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001057 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001058
1059 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001060 EXPECT_FALSE(
1061 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001062}
1063
1064TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001065 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001066 // This test verifies that setting RtpParameters succeeds only if
1067 // the structure contains exactly one encoding.
1068 // TODO(skvlad): Update this test when we start supporting setting parameters
1069 // for each encoding individually.
1070
1071 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001072 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001073 // Two or more encodings should result in failure.
1074 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001076 // Zero encodings should also fail.
1077 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001078 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001079}
1080
1081// Changing the SSRC through RtpParameters is not allowed.
1082TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1083 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001084 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001085 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001086 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001087}
1088
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001089// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001090// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1092 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001093 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001096 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001097 ASSERT_EQ(1u, parameters.encodings.size());
1098 ASSERT_TRUE(parameters.encodings[0].active);
1099 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001100 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001101 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001102
1103 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001104 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001106 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001109}
1110
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001111// Test that SetRtpSendParameters configures the correct encoding channel for
1112// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001113TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1114 SetupForMultiSendStream();
1115 // Create send streams.
1116 for (uint32_t ssrc : kSsrcs4) {
1117 EXPECT_TRUE(
1118 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1119 }
1120 // Configure one stream to be limited by the stream config, another to be
1121 // limited by the global max, and the third one with no per-stream limit
1122 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001123 SetGlobalMaxBitrate(kOpusCodec, 32000);
1124 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1125 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1127
ossu20a4b3f2017-04-27 02:08:52 -07001128 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1129 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1130 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001131
1132 // Remove the global cap; the streams should switch to their respective
1133 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001134 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001135 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1136 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1137 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001138}
1139
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140// Test that GetRtpSendParameters returns the currently configured codecs.
1141TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142 EXPECT_TRUE(SetupSendStream());
1143 cricket::AudioSendParameters parameters;
1144 parameters.codecs.push_back(kIsacCodec);
1145 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001146 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147
solenberg2100c0b2017-03-01 11:29:29 -08001148 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1151 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152}
1153
Florent Castellidacec712018-05-24 16:24:21 +02001154// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1155TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1156 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1157 params.cname = "rtcpcname";
1158 EXPECT_TRUE(SetupSendStream(params));
1159
1160 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1161 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1162}
1163
Florent Castelliabe301f2018-06-12 18:33:49 +02001164TEST_F(WebRtcVoiceEngineTestFake,
1165 DetectRtpSendParameterHeaderExtensionsChange) {
1166 EXPECT_TRUE(SetupSendStream());
1167
1168 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1169 rtp_parameters.header_extensions.emplace_back();
1170
1171 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1172
1173 webrtc::RTCError result =
1174 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1175 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1176}
1177
deadbeefcb443432016-12-12 11:12:36 -08001178// Test that GetRtpSendParameters returns an SSRC.
1179TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1180 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001181 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001182 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001183 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001184}
1185
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001186// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001187TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001188 EXPECT_TRUE(SetupSendStream());
1189 cricket::AudioSendParameters parameters;
1190 parameters.codecs.push_back(kIsacCodec);
1191 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001192 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001193
solenberg2100c0b2017-03-01 11:29:29 -08001194 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001195
1196 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001197 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001198
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001200 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1201 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001202}
1203
minyuececec102017-03-27 13:04:25 -07001204// Test that max_bitrate_bps in send stream config gets updated correctly when
1205// SetRtpSendParameters is called.
1206TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1207 webrtc::test::ScopedFieldTrials override_field_trials(
1208 "WebRTC-Audio-SendSideBwe/Enabled/");
1209 EXPECT_TRUE(SetupSendStream());
1210 cricket::AudioSendParameters send_parameters;
1211 send_parameters.codecs.push_back(kOpusCodec);
1212 SetSendParameters(send_parameters);
1213
1214 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1215 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1216 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1217
1218 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001219 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001220 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001221
1222 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1223 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1224}
1225
Seth Hampson24722b32017-12-22 09:36:42 -08001226// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1227// a value <= 0, setting the parameters returns false.
1228TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1229 EXPECT_TRUE(SetupSendStream());
1230 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1231 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1232 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1233 rtp_parameters.encodings[0].bitrate_priority);
1234
1235 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001236 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001237 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001238 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001239}
1240
1241// Test that the bitrate_priority in the send stream config gets updated when
1242// SetRtpSendParameters is set for the VoiceMediaChannel.
1243TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1244 EXPECT_TRUE(SetupSendStream());
1245 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1246
1247 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1248 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1249 rtp_parameters.encodings[0].bitrate_priority);
1250 double new_bitrate_priority = 2.0;
1251 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001252 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001253
1254 // The priority should get set for both the audio channel's rtp parameters
1255 // and the audio send stream's audio config.
1256 EXPECT_EQ(
1257 new_bitrate_priority,
1258 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1259 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1260}
1261
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001262// Test that GetRtpReceiveParameters returns the currently configured codecs.
1263TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1264 EXPECT_TRUE(SetupRecvStream());
1265 cricket::AudioRecvParameters parameters;
1266 parameters.codecs.push_back(kIsacCodec);
1267 parameters.codecs.push_back(kPcmuCodec);
1268 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1269
1270 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001271 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001272 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1273 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1274 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1275}
1276
deadbeefcb443432016-12-12 11:12:36 -08001277// Test that GetRtpReceiveParameters returns an SSRC.
1278TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1279 EXPECT_TRUE(SetupRecvStream());
1280 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001281 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001282 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001283 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001284}
1285
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001286// Test that if we set/get parameters multiple times, we get the same results.
1287TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1288 EXPECT_TRUE(SetupRecvStream());
1289 cricket::AudioRecvParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
1292 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1293
1294 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001295 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001296
1297 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001298 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001299
1300 // ... And this shouldn't change the params returned by
1301 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001302 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1303 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001304}
1305
deadbeef3bc15102017-04-20 19:25:07 -07001306// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1307// aren't signaled. It should return an empty "RtpEncodingParameters" when
1308// configured to receive an unsignaled stream and no packets have been received
1309// yet, and start returning the SSRC once a packet has been received.
1310TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1311 ASSERT_TRUE(SetupChannel());
1312 // Call necessary methods to configure receiving a default stream as
1313 // soon as it arrives.
1314 cricket::AudioRecvParameters parameters;
1315 parameters.codecs.push_back(kIsacCodec);
1316 parameters.codecs.push_back(kPcmuCodec);
1317 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1318
1319 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1320 // stream. Should return nothing.
1321 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1322
1323 // Set a sink for an unsignaled stream.
1324 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1325 // Value of "0" means "unsignaled stream".
1326 channel_->SetRawAudioSink(0, std::move(fake_sink));
1327
1328 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1329 // in this method means "unsignaled stream".
1330 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1331 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1332 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1333
1334 // Receive PCMU packet (SSRC=1).
1335 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1336
1337 // The |ssrc| member should still be unset.
1338 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1339 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1340 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1341}
1342
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343// Test that we apply codecs properly.
1344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kIsacCodec);
1348 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001349 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001351 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001353 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1354 EXPECT_EQ(96, send_codec_spec.payload_type);
1355 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1356 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1357 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001358 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001359 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001360}
1361
ossu20a4b3f2017-04-27 02:08:52 -07001362// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1363// AudioSendStream.
1364TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kIsacCodec);
1368 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001369 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 parameters.codecs[0].id = 96;
1371 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001372 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001373 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001374 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001375 // Calling SetSendCodec again with same codec which is already set.
1376 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001378 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001379}
1380
ossu20a4b3f2017-04-27 02:08:52 -07001381// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1382// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001383
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001384// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].clockrate = 50000;
1391 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392}
1393
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001394// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].bitrate = 0;
1400 parameters.codecs[0].channels = 0;
1401 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402}
1403
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001404// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kOpusCodec);
1409 parameters.codecs[0].bitrate = 0;
1410 parameters.codecs[0].channels = 0;
1411 parameters.codecs[0].params["stereo"] = "1";
1412 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413}
1414
1415// Test that if channel is 1 for opus and there's no stereo, we fail.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 0;
1421 parameters.codecs[0].channels = 1;
1422 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423}
1424
1425// Test that if channel is 1 for opus and stereo=0, we fail.
1426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 0;
1431 parameters.codecs[0].channels = 1;
1432 parameters.codecs[0].params["stereo"] = "0";
1433 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434}
1435
1436// Test that if channel is 1 for opus and stereo=1, we fail.
1437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].bitrate = 0;
1442 parameters.codecs[0].channels = 1;
1443 parameters.codecs[0].params["stereo"] = "1";
1444 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001453 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001454 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455}
1456
ossu20a4b3f2017-04-27 02:08:52 -07001457// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001459 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001460 cricket::AudioSendParameters parameters;
1461 parameters.codecs.push_back(kOpusCodec);
1462 parameters.codecs[0].bitrate = 0;
1463 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001464 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001465 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466}
1467
ossu20a4b3f2017-04-27 02:08:52 -07001468// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001469TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001470 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 cricket::AudioSendParameters parameters;
1472 parameters.codecs.push_back(kOpusCodec);
1473 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001474 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001475 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001478
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001480 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001481 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001482}
1483
ossu20a4b3f2017-04-27 02:08:52 -07001484// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001491 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001492 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
ossu20a4b3f2017-04-27 02:08:52 -07001495// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001497 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 cricket::AudioSendParameters parameters;
1499 parameters.codecs.push_back(kOpusCodec);
1500 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001501 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001504 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001505
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001506 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001509}
1510
ossu20a4b3f2017-04-27 02:08:52 -07001511// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001513 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001514 cricket::AudioSendParameters parameters;
1515 parameters.codecs.push_back(kOpusCodec);
1516 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001517 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001518 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1519 EXPECT_EQ(111, spec.payload_type);
1520 EXPECT_EQ(96000, spec.target_bitrate_bps);
1521 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001522 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001523 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 30000;
1532 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001544 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001545}
1546
ossu20a4b3f2017-04-27 02:08:52 -07001547// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
1552 parameters.codecs[0].bitrate = 30000;
1553 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001554 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001555 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001556}
1557
stefan13f1a0a2016-11-30 07:22:58 -08001558TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1559 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1560 200000);
1561}
1562
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1564 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1565}
1566
1567TEST_F(WebRtcVoiceEngineTestFake,
1568 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1569 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1570}
1571
1572TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1573 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1574}
1575
Yves Gerey665174f2018-06-19 15:03:05 +02001576TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001577 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1578 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001579 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001580 // Setting max bitrate should keep previous min bitrate
1581 // Setting max bitrate should not reset start bitrate.
1582 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1583 SetSdpBitrateParameters(
1584 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1585 Field(&BitrateConstraints::start_bitrate_bps, -1),
1586 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001587 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001588}
1589
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001590// Test that we can enable NACK with opus as caller.
1591TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001592 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 cricket::AudioSendParameters parameters;
1594 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001595 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1596 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001598 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001600}
1601
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001602// Test that we can enable NACK with opus as callee.
1603TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001604 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001605 cricket::AudioSendParameters parameters;
1606 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001607 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1608 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001611 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001613
Yves Gerey665174f2018-06-19 15:03:05 +02001614 EXPECT_TRUE(
1615 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001617}
1618
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619// Test that we can enable NACK on receive streams.
1620TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001621 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001623 cricket::AudioSendParameters parameters;
1624 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001625 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1626 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1628 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001630 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1631 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632}
1633
1634// Test that we can disable NACK.
1635TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001636 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001637 cricket::AudioSendParameters parameters;
1638 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001639 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1640 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 parameters.codecs.clear();
1645 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648}
1649
1650// Test that we can disable NACK on receive streams.
1651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001652 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001653 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters parameters;
1655 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001656 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1657 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001659 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1660 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 parameters.codecs.clear();
1663 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001665 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1666 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667}
1668
1669// Test that NACK is enabled on a new receive stream.
1670TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 cricket::AudioSendParameters parameters;
1673 parameters.codecs.push_back(kIsacCodec);
1674 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001675 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1676 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_TRUE(AddRecvStream(kSsrcY));
1681 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1682 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1683 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684}
1685
stefanba4c0e42016-02-04 04:12:24 -08001686TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001688 cricket::AudioSendParameters send_parameters;
1689 send_parameters.codecs.push_back(kOpusCodec);
1690 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001692
1693 cricket::AudioRecvParameters recv_parameters;
1694 recv_parameters.codecs.push_back(kIsacCodec);
1695 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001696 EXPECT_TRUE(AddRecvStream(kSsrcX));
1697 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001698 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001699 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001700
ossudedfd282016-06-14 07:12:39 -07001701 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001703 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001704 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001705 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001706}
1707
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001708// Test that we can switch back and forth between Opus and ISAC with CN.
1709TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001711
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001712 cricket::AudioSendParameters opus_parameters;
1713 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001715 {
ossu20a4b3f2017-04-27 02:08:52 -07001716 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1717 EXPECT_EQ(111, spec.payload_type);
1718 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001721 cricket::AudioSendParameters isac_parameters;
1722 isac_parameters.codecs.push_back(kIsacCodec);
1723 isac_parameters.codecs.push_back(kCn16000Codec);
1724 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001726 {
ossu20a4b3f2017-04-27 02:08:52 -07001727 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1728 EXPECT_EQ(103, spec.payload_type);
1729 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001730 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001733 {
ossu20a4b3f2017-04-27 02:08:52 -07001734 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1735 EXPECT_EQ(111, spec.payload_type);
1736 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001737 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001738}
1739
1740// Test that we handle various ways of specifying bitrate.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 cricket::AudioSendParameters parameters;
1744 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001746 {
ossu20a4b3f2017-04-27 02:08:52 -07001747 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1748 EXPECT_EQ(103, spec.payload_type);
1749 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1750 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001751 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752
Yves Gerey665174f2018-06-19 15:03:05 +02001753 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001754 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001755 {
ossu20a4b3f2017-04-27 02:08:52 -07001756 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1757 EXPECT_EQ(103, spec.payload_type);
1758 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1759 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001760 }
Yves Gerey665174f2018-06-19 15:03:05 +02001761 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(103, spec.payload_type);
1766 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1767 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001768 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001769
Yves Gerey665174f2018-06-19 15:03:05 +02001770 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001771 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001772 {
ossu20a4b3f2017-04-27 02:08:52 -07001773 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1774 EXPECT_EQ(0, spec.payload_type);
1775 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1776 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001777 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778
Yves Gerey665174f2018-06-19 15:03:05 +02001779 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 {
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(0, spec.payload_type);
1784 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1785 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001788 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001789 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001790 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001791 {
ossu20a4b3f2017-04-27 02:08:52 -07001792 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1793 EXPECT_EQ(111, spec.payload_type);
1794 EXPECT_STREQ("opus", spec.format.name.c_str());
1795 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001796 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797}
1798
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001799// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001801 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 cricket::AudioSendParameters parameters;
1803 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001804}
1805
1806// Test that we can set send codecs even with telephone-event codec as the first
1807// one on the list.
1808TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001809 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001810 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001811 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 parameters.codecs.push_back(kIsacCodec);
1813 parameters.codecs.push_back(kPcmuCodec);
1814 parameters.codecs[0].id = 98; // DTMF
1815 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(96, spec.payload_type);
1819 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001820 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001821 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001822}
1823
Harald Alvestranda1f66612018-02-21 11:24:23 +01001824// Test that CanInsertDtmf() is governed by the send flag
1825TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1826 EXPECT_TRUE(SetupSendStream());
1827 cricket::AudioSendParameters parameters;
1828 parameters.codecs.push_back(kTelephoneEventCodec1);
1829 parameters.codecs.push_back(kPcmuCodec);
1830 parameters.codecs[0].id = 98; // DTMF
1831 parameters.codecs[1].id = 96;
1832 SetSendParameters(parameters);
1833 EXPECT_FALSE(channel_->CanInsertDtmf());
1834 SetSend(true);
1835 EXPECT_TRUE(channel_->CanInsertDtmf());
1836 SetSend(false);
1837 EXPECT_FALSE(channel_->CanInsertDtmf());
1838}
1839
solenberg31642aa2016-03-14 08:00:37 -07001840// Test that payload type range is limited for telephone-event codec.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001842 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001843 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001844 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001845 parameters.codecs.push_back(kIsacCodec);
1846 parameters.codecs[0].id = 0; // DTMF
1847 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001848 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001849 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001850 EXPECT_TRUE(channel_->CanInsertDtmf());
1851 parameters.codecs[0].id = 128; // DTMF
1852 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1853 EXPECT_FALSE(channel_->CanInsertDtmf());
1854 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001855 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001856 EXPECT_TRUE(channel_->CanInsertDtmf());
1857 parameters.codecs[0].id = -1; // DTMF
1858 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1859 EXPECT_FALSE(channel_->CanInsertDtmf());
1860}
1861
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001862// Test that we can set send codecs even with CN codec as the first
1863// one on the list.
1864TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001865 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001866 cricket::AudioSendParameters parameters;
1867 parameters.codecs.push_back(kCn16000Codec);
1868 parameters.codecs.push_back(kIsacCodec);
1869 parameters.codecs.push_back(kPcmuCodec);
1870 parameters.codecs[0].id = 98; // wideband CN
1871 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001873 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1874 EXPECT_EQ(96, send_codec_spec.payload_type);
1875 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001876 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001877}
1878
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001879// Test that we set VAD and DTMF types correctly as caller.
1880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001881 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters parameters;
1883 parameters.codecs.push_back(kIsacCodec);
1884 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001885 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 parameters.codecs.push_back(kCn16000Codec);
1887 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001888 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 parameters.codecs[0].id = 96;
1890 parameters.codecs[2].id = 97; // wideband CN
1891 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_EQ(96, send_codec_spec.payload_type);
1895 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001896 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001898 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001899 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900}
1901
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001902// Test that we set VAD and DTMF types correctly as callee.
1903TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001904 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 cricket::AudioSendParameters parameters;
1906 parameters.codecs.push_back(kIsacCodec);
1907 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001908 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 parameters.codecs.push_back(kCn16000Codec);
1910 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001911 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001912 parameters.codecs[0].id = 96;
1913 parameters.codecs[2].id = 97; // wideband CN
1914 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001916 EXPECT_TRUE(
1917 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001918
ossu20a4b3f2017-04-27 02:08:52 -07001919 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1920 EXPECT_EQ(96, send_codec_spec.payload_type);
1921 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001922 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001923 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001924 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001925 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001926}
1927
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928// Test that we only apply VAD if we have a CN codec that matches the
1929// send codec clockrate.
1930TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001931 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001933 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 parameters.codecs.push_back(kIsacCodec);
1935 parameters.codecs.push_back(kCn16000Codec);
1936 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001937 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001938 {
ossu20a4b3f2017-04-27 02:08:52 -07001939 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1940 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001941 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001943 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001945 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001946 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001947 {
ossu20a4b3f2017-04-27 02:08:52 -07001948 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1949 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001950 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001951 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001952 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001954 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001955 {
ossu20a4b3f2017-04-27 02:08:52 -07001956 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1957 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001958 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001959 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001960 }
Brave Yao5225dd82015-03-26 07:39:19 +08001961 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001962 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001963 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001964 {
ossu20a4b3f2017-04-27 02:08:52 -07001965 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1966 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001967 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001968 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969}
1970
1971// Test that we perform case-insensitive matching of codec names.
1972TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001973 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001974 cricket::AudioSendParameters parameters;
1975 parameters.codecs.push_back(kIsacCodec);
1976 parameters.codecs.push_back(kPcmuCodec);
1977 parameters.codecs.push_back(kCn16000Codec);
1978 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001979 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0].name = "iSaC";
1981 parameters.codecs[0].id = 96;
1982 parameters.codecs[2].id = 97; // wideband CN
1983 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001985 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1986 EXPECT_EQ(96, send_codec_spec.payload_type);
1987 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001988 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001989 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001990 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001991 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001992}
1993
stefanba4c0e42016-02-04 04:12:24 -08001994class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1995 public:
1996 WebRtcVoiceEngineWithSendSideBweTest()
1997 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1998};
1999
2000TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2001 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002002 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002003 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002004 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2005 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2006 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002007 extension.id);
2008 return;
2009 }
2010 }
2011 FAIL() << "Transport sequence number extension not in header-extension list.";
2012}
2013
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002014// Test support for audio level header extension.
2015TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002016 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002017}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002018TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002019 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002020}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002021
solenbergd4adce42016-11-17 06:26:52 -08002022// Test support for transport sequence number header extension.
2023TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2024 TestSetSendRtpHeaderExtensions(
2025 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002026}
solenbergd4adce42016-11-17 06:26:52 -08002027TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2028 TestSetRecvRtpHeaderExtensions(
2029 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002030}
2031
solenberg1ac56142015-10-13 03:58:19 -07002032// Test that we can create a channel and start sending on it.
2033TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002034 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002035 SetSendParameters(send_parameters_);
2036 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002037 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002038 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002039 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002040}
2041
2042// Test that a channel will send if and only if it has a source and is enabled
2043// for sending.
2044TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002045 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002046 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002047 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002048 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002049 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2050 SetAudioSend(kSsrcX, true, &fake_source_);
2051 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2052 SetAudioSend(kSsrcX, true, nullptr);
2053 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002054}
2055
solenberg94218532016-06-16 10:53:22 -07002056// Test that a channel is muted/unmuted.
2057TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2058 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002059 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002060 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2061 SetAudioSend(kSsrcX, true, nullptr);
2062 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2063 SetAudioSend(kSsrcX, false, nullptr);
2064 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002065}
2066
solenberg6d6e7c52016-04-13 09:07:30 -07002067// Test that SetSendParameters() does not alter a stream's send state.
2068TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2069 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002070 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002071
2072 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002073 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002074 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002075
2076 // Changing RTP header extensions will recreate the AudioSendStream.
2077 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002078 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002079 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002080 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002081
2082 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002083 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002084 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002085
2086 // Changing RTP header extensions will recreate the AudioSendStream.
2087 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002088 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002090}
2091
solenberg1ac56142015-10-13 03:58:19 -07002092// Test that we can create a channel and start playing out on it.
2093TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002094 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002095 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002096 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002098 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002099 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100}
2101
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102// Test that we can add and remove send streams.
2103TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2104 SetupForMultiSendStream();
2105
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002107 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108
solenbergc96df772015-10-21 13:01:53 -07002109 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002110 EXPECT_TRUE(
2111 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002112 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002114 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 }
tfarina5237aaf2015-11-10 23:44:30 -08002116 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117
solenbergc96df772015-10-21 13:01:53 -07002118 // Delete the send streams.
2119 for (uint32_t ssrc : kSsrcs4) {
2120 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002121 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002122 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123 }
solenbergc96df772015-10-21 13:01:53 -07002124 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125}
2126
2127// Test SetSendCodecs correctly configure the codecs in all send streams.
2128TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2129 SetupForMultiSendStream();
2130
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002132 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002133 EXPECT_TRUE(
2134 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 }
2136
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002137 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002139 parameters.codecs.push_back(kIsacCodec);
2140 parameters.codecs.push_back(kCn16000Codec);
2141 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002142 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143
2144 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002145 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002146 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2147 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002148 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2149 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002150 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002151 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 }
2153
minyue7a973442016-10-20 03:27:12 -07002154 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002155 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002156 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002157 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002158 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2159 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002160 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2161 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002162 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
2164}
2165
2166// Test we can SetSend on all send streams correctly.
2167TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2168 SetupForMultiSendStream();
2169
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002170 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002171 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002172 EXPECT_TRUE(
2173 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002174 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002175 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176 }
2177
2178 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002179 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002181 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002182 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184
2185 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002186 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002188 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002189 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
2191}
2192
2193// Test we can set the correct statistics on all send streams.
2194TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2195 SetupForMultiSendStream();
2196
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002198 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002199 EXPECT_TRUE(
2200 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002201 }
solenberg85a04962015-10-27 03:35:21 -07002202
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002203 // Create a receive stream to check that none of the send streams end up in
2204 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002205 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002206
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002208 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002209 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002210 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211
solenberg85a04962015-10-27 03:35:21 -07002212 // Check stats for the added streams.
2213 {
2214 cricket::VoiceMediaInfo info;
2215 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216
solenberg85a04962015-10-27 03:35:21 -07002217 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002218 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002219 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002220 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002221 }
hbos1acfbd22016-11-17 23:43:29 -08002222 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002223
2224 // We have added one receive stream. We should see empty stats.
2225 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002226 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 }
solenberg1ac56142015-10-13 03:58:19 -07002228
solenberg2100c0b2017-03-01 11:29:29 -08002229 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002230 {
2231 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002232 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002233 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002234 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002235 EXPECT_EQ(0u, info.receivers.size());
2236 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002237
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002238 // Deliver a new packet - a default receive stream should be created and we
2239 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002240 {
2241 cricket::VoiceMediaInfo info;
2242 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2243 SetAudioReceiveStreamStats();
2244 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002245 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002246 EXPECT_EQ(1u, info.receivers.size());
2247 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002248 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002249 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002250}
2251
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002252// Test that we can add and remove receive streams, and do proper send/playout.
2253// We can receive on multiple streams while sending one stream.
2254TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002255 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002256
solenberg1ac56142015-10-13 03:58:19 -07002257 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002258 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002259 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002260
solenberg1ac56142015-10-13 03:58:19 -07002261 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002263 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002265
solenberg1ac56142015-10-13 03:58:19 -07002266 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002267 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002268
2269 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002270 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2271 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2272 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002273
2274 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002275 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002276 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002277
2278 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002279 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002280 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2281 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002282
aleloi84ef6152016-08-04 05:28:21 -07002283 // Restart playout and make sure recv streams are played out.
2284 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2286 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
aleloi84ef6152016-08-04 05:28:21 -07002288 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2290 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291}
2292
wu@webrtc.org97077a32013-10-25 21:18:33 +00002293TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002294 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002295 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2296 .Times(1)
2297 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002298 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2299 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002300 send_parameters_.options.tx_agc_target_dbov = 3;
2301 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2302 send_parameters_.options.tx_agc_limiter = true;
2303 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002304 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2305 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2306 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002307 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002308}
2309
minyue6b825df2016-10-31 04:08:32 -07002310TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2311 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002312 send_parameters_.options.audio_network_adaptor = true;
2313 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002314 SetSendParameters(send_parameters_);
2315 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002316 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002317}
2318
2319TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2320 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002321 send_parameters_.options.audio_network_adaptor = true;
2322 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002323 SetSendParameters(send_parameters_);
2324 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002325 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002326 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002327 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002328 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002329 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002330}
2331
2332TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2333 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002334 send_parameters_.options.audio_network_adaptor = true;
2335 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002336 SetSendParameters(send_parameters_);
2337 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002338 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002339 const int initial_num = call_.GetNumCreatedSendStreams();
2340 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002341 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002342 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2343 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002344 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002345 // AudioSendStream not expected to be recreated.
2346 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2347 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002348 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002349}
2350
michaelt6672b262017-01-11 10:17:59 -08002351class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2352 : public WebRtcVoiceEngineTestFake {
2353 public:
2354 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2355 : WebRtcVoiceEngineTestFake(
2356 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2357 "Enabled/") {}
2358};
2359
2360TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2361 EXPECT_TRUE(SetupSendStream());
2362 cricket::AudioSendParameters parameters;
2363 parameters.codecs.push_back(kOpusCodec);
2364 SetSendParameters(parameters);
2365 const int initial_num = call_.GetNumCreatedSendStreams();
2366 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2367
2368 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2369 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002370 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2371 constexpr int kMinOverheadBps =
2372 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002373
2374 constexpr int kOpusMinBitrateBps = 6000;
2375 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002376 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002377 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002378 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002379 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002380
Oskar Sundbom78807582017-11-16 11:09:55 +01002381 parameters.options.audio_network_adaptor = true;
2382 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002383 SetSendParameters(parameters);
2384
ossu11bfc532017-02-16 05:37:06 -08002385 constexpr int kMinOverheadWithAnaBps =
2386 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002387
2388 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002389 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002390
minyuececec102017-03-27 13:04:25 -07002391 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002392 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002393}
2394
minyuececec102017-03-27 13:04:25 -07002395// This test is similar to
2396// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2397// additional field trial.
2398TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2399 SetRtpSendParameterUpdatesMaxBitrate) {
2400 EXPECT_TRUE(SetupSendStream());
2401 cricket::AudioSendParameters send_parameters;
2402 send_parameters.codecs.push_back(kOpusCodec);
2403 SetSendParameters(send_parameters);
2404
2405 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2406 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2407 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2408
2409 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002410 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002411 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002412
2413 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2414#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2415 constexpr int kMinOverhead = 3333;
2416#else
2417 constexpr int kMinOverhead = 6666;
2418#endif
2419 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2420}
2421
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002423// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002425 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002426 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2430 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002431 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002432 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002433 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002434 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002435 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002436 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002437 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438
solenberg85a04962015-10-27 03:35:21 -07002439 // Check stats for the added streams.
2440 {
2441 cricket::VoiceMediaInfo info;
2442 EXPECT_EQ(true, channel_->GetStats(&info));
2443
2444 // We have added one send stream. We should see the stats we've set.
2445 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002446 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002447 // We have added one receive stream. We should see empty stats.
2448 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002449 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002450 }
solenberg1ac56142015-10-13 03:58:19 -07002451
solenberg566ef242015-11-06 15:34:49 -08002452 // Start sending - this affects some reported stats.
2453 {
2454 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002455 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002456 EXPECT_EQ(true, channel_->GetStats(&info));
2457 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002458 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002459 }
2460
solenberg2100c0b2017-03-01 11:29:29 -08002461 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002462 {
2463 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002465 EXPECT_EQ(true, channel_->GetStats(&info));
2466 EXPECT_EQ(1u, info.senders.size());
2467 EXPECT_EQ(0u, info.receivers.size());
2468 }
solenberg1ac56142015-10-13 03:58:19 -07002469
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002470 // Deliver a new packet - a default receive stream should be created and we
2471 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002472 {
2473 cricket::VoiceMediaInfo info;
2474 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2475 SetAudioReceiveStreamStats();
2476 EXPECT_EQ(true, channel_->GetStats(&info));
2477 EXPECT_EQ(1u, info.senders.size());
2478 EXPECT_EQ(1u, info.receivers.size());
2479 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002480 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002481 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482}
2483
2484// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002485// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2489 EXPECT_TRUE(AddRecvStream(kSsrcY));
2490 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491}
2492
2493// Test that the local SSRC is the same on sending and receiving channels if the
2494// receive channel is created before the send channel.
2495TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002496 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002497 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002498 EXPECT_TRUE(
2499 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002500 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2501 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502}
2503
2504// Test that we can properly receive packets.
2505TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002507 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002509
Yves Gerey665174f2018-06-19 15:03:05 +02002510 EXPECT_TRUE(
2511 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512}
2513
2514// Test that we can properly receive packets on multiple streams.
2515TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002516 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002517 const uint32_t ssrc1 = 1;
2518 const uint32_t ssrc2 = 2;
2519 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002520 EXPECT_TRUE(AddRecvStream(ssrc1));
2521 EXPECT_TRUE(AddRecvStream(ssrc2));
2522 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002524 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002525 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002527 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528 }
mflodman3d7db262016-04-29 00:57:13 -07002529
2530 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2531 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2532 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2533
2534 EXPECT_EQ(s1.received_packets(), 0);
2535 EXPECT_EQ(s2.received_packets(), 0);
2536 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002537
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(s1.received_packets(), 0);
2540 EXPECT_EQ(s2.received_packets(), 0);
2541 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002542
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002544 EXPECT_EQ(s1.received_packets(), 1);
2545 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2546 EXPECT_EQ(s2.received_packets(), 0);
2547 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002548
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002549 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002550 EXPECT_EQ(s1.received_packets(), 1);
2551 EXPECT_EQ(s2.received_packets(), 1);
2552 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2553 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002554
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002556 EXPECT_EQ(s1.received_packets(), 1);
2557 EXPECT_EQ(s2.received_packets(), 1);
2558 EXPECT_EQ(s3.received_packets(), 1);
2559 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002560
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2562 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2563 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564}
2565
solenberg2100c0b2017-03-01 11:29:29 -08002566// Test that receiving on an unsignaled stream works (a stream is created).
2567TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002568 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002569 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002570
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002572
Mirko Bonadeif859e552018-05-30 15:31:29 +02002573 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002574 EXPECT_TRUE(
2575 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002576}
2577
Seth Hampson5897a6e2018-04-03 11:16:33 -07002578// Tests that when we add a stream without SSRCs, but contains a stream_id
2579// that it is stored and its stream id is later used when the first packet
2580// arrives to properly create a receive stream with a sync label.
2581TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2582 const char kSyncLabel[] = "sync_label";
2583 EXPECT_TRUE(SetupChannel());
2584 cricket::StreamParams unsignaled_stream;
2585 unsignaled_stream.set_stream_ids({kSyncLabel});
2586 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2587 // The stream shouldn't have been created at this point because it doesn't
2588 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002589 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002590
2591 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2592
Mirko Bonadeif859e552018-05-30 15:31:29 +02002593 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002594 EXPECT_TRUE(
2595 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2596 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2597
2598 // Removing the unsignaled stream clears the cached parameters. If a new
2599 // default unsignaled receive stream is created it will not have a sync group.
2600 channel_->RemoveRecvStream(0);
2601 channel_->RemoveRecvStream(kSsrc1);
2602
2603 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2604
Mirko Bonadeif859e552018-05-30 15:31:29 +02002605 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002606 EXPECT_TRUE(
2607 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2608 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2609}
2610
solenberg2100c0b2017-03-01 11:29:29 -08002611// Test that receiving N unsignaled stream works (streams will be created), and
2612// that packets are forwarded to them all.
2613TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002614 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002615 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002616 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2617
solenberg2100c0b2017-03-01 11:29:29 -08002618 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002619 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002620 rtc::SetBE32(&packet[8], ssrc);
2621 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002622
solenberg2100c0b2017-03-01 11:29:29 -08002623 // Verify we have one new stream for each loop iteration.
2624 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002625 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2626 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002627 }
mflodman3d7db262016-04-29 00:57:13 -07002628
solenberg2100c0b2017-03-01 11:29:29 -08002629 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002630 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002631 rtc::SetBE32(&packet[8], ssrc);
2632 DeliverPacket(packet, sizeof(packet));
2633
solenbergebb349d2017-03-13 05:46:15 -07002634 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002635 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2636 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2637 }
2638
2639 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2640 constexpr uint32_t kAnotherSsrc = 667;
2641 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002642 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002643
2644 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002645 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002646 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002647 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002648 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2649 EXPECT_EQ(2, streams[i]->received_packets());
2650 }
2651 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2652 EXPECT_EQ(1, streams[i]->received_packets());
2653 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002654 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002655}
2656
solenberg2100c0b2017-03-01 11:29:29 -08002657// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002658// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002659TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002660 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002661 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002662 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2663
2664 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002665 const uint32_t signaled_ssrc = 1;
2666 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002667 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002668 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002669 EXPECT_TRUE(
2670 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002671 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002672
2673 // Note that the first unknown SSRC cannot be 0, because we only support
2674 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002675 const uint32_t unsignaled_ssrc = 7011;
2676 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002677 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002678 EXPECT_TRUE(
2679 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002680 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002681
2682 DeliverPacket(packet, sizeof(packet));
2683 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2684
2685 rtc::SetBE32(&packet[8], signaled_ssrc);
2686 DeliverPacket(packet, sizeof(packet));
2687 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002688 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002689}
2690
solenberg4904fb62017-02-17 12:01:14 -08002691// Two tests to verify that adding a receive stream with the same SSRC as a
2692// previously added unsignaled stream will only recreate underlying stream
2693// objects if the stream parameters have changed.
2694TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2695 EXPECT_TRUE(SetupChannel());
2696
2697 // Spawn unsignaled stream with SSRC=1.
2698 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002699 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002700 EXPECT_TRUE(
2701 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002702
2703 // Verify that the underlying stream object in Call is not recreated when a
2704 // stream with SSRC=1 is added.
2705 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002706 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002707 int audio_receive_stream_id = streams.front()->id();
2708 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002709 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002710 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2711}
2712
2713TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2714 EXPECT_TRUE(SetupChannel());
2715
2716 // Spawn unsignaled stream with SSRC=1.
2717 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002718 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002719 EXPECT_TRUE(
2720 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002721
2722 // Verify that the underlying stream object in Call *is* recreated when a
2723 // stream with SSRC=1 is added, and which has changed stream parameters.
2724 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002725 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002726 int audio_receive_stream_id = streams.front()->id();
2727 cricket::StreamParams stream_params;
2728 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002729 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002730 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002731 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002732 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2733}
2734
solenberg1ac56142015-10-13 03:58:19 -07002735// Test that AddRecvStream creates new stream.
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002738 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739}
2740
2741// Test that after adding a recv stream, we do not decode more codecs than
2742// those previously passed into SetRecvCodecs.
2743TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002744 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002745 cricket::AudioRecvParameters parameters;
2746 parameters.codecs.push_back(kIsacCodec);
2747 parameters.codecs.push_back(kPcmuCodec);
2748 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002749 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002750 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2751 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2752 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753}
2754
2755// Test that we properly clean up any streams that were added, even if
2756// not explicitly removed.
2757TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002758 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002759 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(1));
2761 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002762
Mirko Bonadeif859e552018-05-30 15:31:29 +02002763 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2764 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765 delete channel_;
2766 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002767 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2768 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769}
2770
wu@webrtc.org78187522013-10-07 23:32:02 +00002771TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002773 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002774}
2775
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002776TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002777 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002778 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002779 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002780}
2781
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002782// Test the InsertDtmf on default send stream as caller.
2783TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002784 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785}
2786
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002787// Test the InsertDtmf on default send stream as callee
2788TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002789 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002790}
2791
2792// Test the InsertDtmf on specified send stream as caller.
2793TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002794 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002795}
2796
2797// Test the InsertDtmf on specified send stream as callee.
2798TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002799 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800}
2801
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002803 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002804 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002805 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2806 .Times(9)
2807 .WillRepeatedly(Return(false));
2808 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2809 .Times(4)
2810 .WillRepeatedly(Return(false));
2811 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2812 .Times(2)
2813 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002814
Mirko Bonadeif859e552018-05-30 15:31:29 +02002815 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002816 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817
solenberg246b8172015-12-08 09:50:23 -08002818 // Nothing set in AudioOptions, so everything should be as default.
2819 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002820 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002821 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002822 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002823 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824
2825 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002826 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002828 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830
2831 // Turn echo cancellation back on, with settings, and make sure
2832 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002833 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002835 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002836 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002838 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2839 // control.
solenberg76377c52017-02-21 00:54:31 -08002840 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2841 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002842 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002843 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002844
2845 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002846 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2847 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002848 send_parameters_.options.delay_agnostic_aec = false;
2849 send_parameters_.options.extended_filter_aec = false;
2850 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002851 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002852
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002853 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002854 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2855 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002856 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002857 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002858
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002860 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002862 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002863 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002864 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002865 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866
2867 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002868 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002870 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002871 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002873 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002875 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002876 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002878 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002879 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002880 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002881 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2882 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002883 send_parameters_.options.noise_suppression = false;
2884 send_parameters_.options.highpass_filter = false;
2885 send_parameters_.options.typing_detection = false;
2886 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002887 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002888 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
solenberg1ac56142015-10-13 03:58:19 -07002890 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002891 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002893 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002894 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002895 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002896 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2897 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002898 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899}
2900
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002901TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002902 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002903 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2904 .Times(8)
2905 .WillRepeatedly(Return(false));
2906 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2907 .Times(8)
2908 .WillRepeatedly(Return(false));
2909 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2910 .Times(8)
2911 .WillRepeatedly(Return(false));
2912 EXPECT_CALL(adm_, RecordingIsInitialized())
2913 .Times(2)
2914 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002915 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2916 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002917 webrtc::AudioProcessing::Config apm_config;
2918 EXPECT_CALL(*apm_, GetConfig())
2919 .Times(10)
2920 .WillRepeatedly(ReturnPointee(&apm_config));
2921 EXPECT_CALL(*apm_, ApplyConfig(_))
2922 .Times(10)
2923 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002924 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002925
kwiberg686a8ef2016-02-26 03:00:35 -08002926 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002927 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002928 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002929 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002930 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002931 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932
2933 // Have to add a stream to make SetSend work.
2934 cricket::StreamParams stream1;
2935 stream1.ssrcs.push_back(1);
2936 channel1->AddSendStream(stream1);
2937 cricket::StreamParams stream2;
2938 stream2.ssrcs.push_back(2);
2939 channel2->AddSendStream(stream2);
2940
2941 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002942 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002943 parameters_options_all.options.echo_cancellation = true;
2944 parameters_options_all.options.auto_gain_control = true;
2945 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002946 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2947 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002948 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002949 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002952 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002953 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002954 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002955 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956
2957 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002958 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002959 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002960 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2961 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002962 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002963 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002964 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002965 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002966 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002967 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002968 expected_options.echo_cancellation = true;
2969 expected_options.auto_gain_control = true;
2970 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002971 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972
2973 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002974 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002975 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002976 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2977 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002980 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002981 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002982 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002983 expected_options.echo_cancellation = true;
2984 expected_options.auto_gain_control = false;
2985 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002986 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987
solenberg76377c52017-02-21 00:54:31 -08002988 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2989 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002990 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002991 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002992 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002993 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002994 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995
solenberg76377c52017-02-21 00:54:31 -08002996 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2997 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002998 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002999 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003002 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003
solenberg76377c52017-02-21 00:54:31 -08003004 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3005 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003006 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003007 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003008 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003009 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003010 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003013 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3014 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003015 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3016 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08003017 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3018 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003019 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003020 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003021 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003022 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003023 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01003024 expected_options.echo_cancellation = true;
3025 expected_options.auto_gain_control = false;
3026 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003027 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028}
3029
wu@webrtc.orgde305012013-10-31 15:40:38 +00003030// This test verifies DSCP settings are properly applied on voice media channel.
3031TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003032 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003033 cricket::FakeNetworkInterface network_interface;
3034 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003035 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003036
peahb1c9d1d2017-07-25 15:45:24 -07003037 webrtc::AudioProcessing::Config apm_config;
3038 EXPECT_CALL(*apm_, GetConfig())
3039 .Times(3)
3040 .WillRepeatedly(ReturnPointee(&apm_config));
3041 EXPECT_CALL(*apm_, ApplyConfig(_))
3042 .Times(3)
3043 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003044 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003045
solenbergbc37fc82016-04-04 09:54:44 -07003046 channel.reset(
3047 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003048 channel->SetInterface(&network_interface);
3049 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3050 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3051
3052 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003053 channel.reset(
3054 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003055 channel->SetInterface(&network_interface);
3056 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3057
3058 // Verify that setting the option to false resets the
3059 // DiffServCodePoint.
3060 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003061 channel.reset(
3062 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003063 channel->SetInterface(&network_interface);
3064 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3065 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3066
3067 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003068}
3069
solenberg4bac9c52015-10-09 02:32:53 -07003070TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003071 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003072 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003073 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003074 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003076 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3077 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3078 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003079}
3080
solenberg2100c0b2017-03-01 11:29:29 -08003081TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003082 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003083
3084 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003085 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003086 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3087
3088 // Should remember the volume "2" which will be set on new unsignaled streams,
3089 // and also set the gain to 2 on existing unsignaled streams.
3090 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3091 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3092
3093 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3094 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3095 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3096 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3097 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3098 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3099
3100 // Setting gain with SSRC=0 should affect all unsignaled streams.
3101 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003102 if (kMaxUnsignaledRecvStreams > 1) {
3103 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3104 }
solenberg2100c0b2017-03-01 11:29:29 -08003105 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3106
3107 // Setting gain on an individual stream affects only that.
3108 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003109 if (kMaxUnsignaledRecvStreams > 1) {
3110 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3111 }
solenberg2100c0b2017-03-01 11:29:29 -08003112 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003113}
3114
Seth Hampson845e8782018-03-02 11:34:10 -08003115TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003116 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003117 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003118
solenbergff976312016-03-30 23:28:51 -07003119 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003120 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003121 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003122 // Creating two channels to make sure that sync label is set properly for both
3123 // the default voice channel and following ones.
3124 EXPECT_TRUE(channel_->AddRecvStream(sp));
3125 sp.ssrcs[0] += 1;
3126 EXPECT_TRUE(channel_->AddRecvStream(sp));
3127
Mirko Bonadeif859e552018-05-30 15:31:29 +02003128 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003129 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003130 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003131 << "SyncGroup should be set based on stream id";
3132 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003133 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003134 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003135}
3136
solenberg3a941542015-11-16 07:34:50 -08003137// TODO(solenberg): Remove, once recv streams are configured through Call.
3138// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003139TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003140 // Test that setting the header extensions results in the expected state
3141 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003142 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 ssrcs.push_back(223);
3144 ssrcs.push_back(224);
3145
solenbergff976312016-03-30 23:28:51 -07003146 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003147 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003148 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003149 EXPECT_TRUE(
3150 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003151 }
3152
Mirko Bonadeif859e552018-05-30 15:31:29 +02003153 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003154 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003155 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003156 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003157 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003158 }
3159
3160 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003161 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003162 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003163 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003164 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003165 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003166 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003167 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003168 EXPECT_NE(nullptr, s);
3169 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003170 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3171 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003172 for (const auto& s_ext : s_exts) {
3173 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003174 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003175 }
3176 }
3177 }
3178 }
3179
3180 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003181 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003182 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003183 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003184 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003185 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003186 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003187}
3188
3189TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3190 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003191 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003192 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003193 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003194 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3195 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003197 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003198
solenbergff976312016-03-30 23:28:51 -07003199 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 cricket::WebRtcVoiceMediaChannel* media_channel =
3201 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003202 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003203 EXPECT_TRUE(media_channel->AddRecvStream(
3204 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3205
Mirko Bonadeif859e552018-05-30 15:31:29 +02003206 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003207 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003208 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003209 EXPECT_EQ(0, s->received_packets());
3210 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3211 EXPECT_EQ(1, s->received_packets());
3212 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3213 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214}
Minyue2013aec2015-05-13 14:14:42 +02003215
solenberg0a617e22015-10-20 15:49:38 -07003216// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003217// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003218TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003219 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003220 EXPECT_TRUE(AddRecvStream(kSsrcY));
3221 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003222 EXPECT_TRUE(
3223 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003224 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3225 EXPECT_TRUE(AddRecvStream(kSsrcW));
3226 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003227}
3228
solenberg7602aab2016-11-14 11:30:07 -08003229TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3230 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003232 EXPECT_TRUE(
3233 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003234 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3235 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3236 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003237 EXPECT_TRUE(
3238 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003239 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3240 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003241}
stefan658910c2015-09-03 05:48:32 -07003242
deadbeef884f5852016-01-15 09:20:04 -08003243TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003244 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003245 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3246 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003247
3248 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003249 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3250 EXPECT_TRUE(AddRecvStream(kSsrcX));
3251 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003252
3253 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003254 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3255 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003256
3257 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003258 channel_->SetRawAudioSink(kSsrcX, nullptr);
3259 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003260}
3261
solenberg2100c0b2017-03-01 11:29:29 -08003262TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003263 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003264 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3265 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003266 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3267 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003268
3269 // Should be able to set a default sink even when no stream exists.
3270 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3271
solenberg2100c0b2017-03-01 11:29:29 -08003272 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3273 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003274 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003276
3277 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003278 channel_->SetRawAudioSink(kSsrc0, nullptr);
3279 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003280
3281 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003282 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3283 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003284
3285 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003287 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003288 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3289
3290 // Spawn another unsignaled stream - it should be assigned the default sink
3291 // and the previous unsignaled stream should lose it.
3292 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3293 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3294 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3295 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003296 if (kMaxUnsignaledRecvStreams > 1) {
3297 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3298 }
solenberg2100c0b2017-03-01 11:29:29 -08003299 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3300
3301 // Reset the default sink - the second unsignaled stream should lose it.
3302 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003303 if (kMaxUnsignaledRecvStreams > 1) {
3304 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3305 }
solenberg2100c0b2017-03-01 11:29:29 -08003306 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3307
3308 // Try setting the default sink while two streams exists.
3309 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003310 if (kMaxUnsignaledRecvStreams > 1) {
3311 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3312 }
solenberg2100c0b2017-03-01 11:29:29 -08003313 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3314
3315 // Try setting the sink for the first unsignaled stream using its known SSRC.
3316 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003317 if (kMaxUnsignaledRecvStreams > 1) {
3318 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3319 }
solenberg2100c0b2017-03-01 11:29:29 -08003320 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003321 if (kMaxUnsignaledRecvStreams > 1) {
3322 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3323 }
deadbeef884f5852016-01-15 09:20:04 -08003324}
3325
skvlad7a43d252016-03-22 15:32:27 -07003326// Test that, just like the video channel, the voice channel communicates the
3327// network state to the call.
3328TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003329 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003330
3331 EXPECT_EQ(webrtc::kNetworkUp,
3332 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3333 EXPECT_EQ(webrtc::kNetworkUp,
3334 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3335
3336 channel_->OnReadyToSend(false);
3337 EXPECT_EQ(webrtc::kNetworkDown,
3338 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3339 EXPECT_EQ(webrtc::kNetworkUp,
3340 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3341
3342 channel_->OnReadyToSend(true);
3343 EXPECT_EQ(webrtc::kNetworkUp,
3344 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3345 EXPECT_EQ(webrtc::kNetworkUp,
3346 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3347}
3348
aleloi18e0b672016-10-04 02:45:47 -07003349// Test that playout is still started after changing parameters
3350TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3351 SetupRecvStream();
3352 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003353 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003354
3355 // Changing RTP header extensions will recreate the AudioReceiveStream.
3356 cricket::AudioRecvParameters parameters;
3357 parameters.extensions.push_back(
3358 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3359 channel_->SetRecvParameters(parameters);
3360
solenberg2100c0b2017-03-01 11:29:29 -08003361 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003362}
3363
Zhi Huangfa266ef2017-12-13 10:27:46 -08003364// Tests when GetSources is called with non-existing ssrc, it will return an
3365// empty list of RtpSource without crashing.
3366TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3367 // Setup an recv stream with |kSsrcX|.
3368 SetupRecvStream();
3369 cricket::WebRtcVoiceMediaChannel* media_channel =
3370 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3371 // Call GetSources with |kSsrcY| which doesn't exist.
3372 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3373 EXPECT_EQ(0u, sources.size());
3374}
3375
stefan658910c2015-09-03 05:48:32 -07003376// Tests that the library initializes and shuts down properly.
3377TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003378 // If the VoiceEngine wants to gather available codecs early, that's fine but
3379 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003380 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003381 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003382 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003383 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003384 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003385 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003386 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003387 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003388 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003389 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003390 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3391 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003392 EXPECT_TRUE(channel != nullptr);
3393 delete channel;
solenbergff976312016-03-30 23:28:51 -07003394}
stefan658910c2015-09-03 05:48:32 -07003395
solenbergff976312016-03-30 23:28:51 -07003396// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003397TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3398 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003399 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003400 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003401 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003402 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003403 {
peaha9cc40b2017-06-29 08:32:09 -07003404 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003405 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003406 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003407 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003408 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003409 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003410 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003411 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003412 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003413 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3414 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3415 EXPECT_TRUE(channel != nullptr);
3416 delete channel;
3417 }
stefan658910c2015-09-03 05:48:32 -07003418}
3419
ossu20a4b3f2017-04-27 02:08:52 -07003420// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3421TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003422 // TODO(ossu): Why are the payload types of codecs with non-static payload
3423 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003424 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003425 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003426 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003427 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003428 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003429 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003430 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003431 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003432 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3433 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3434 (clockrate == 0 || codec.clockrate == clockrate);
3435 };
3436 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003437 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003438 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003439 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003440 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003441 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003442 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003443 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003444 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003445 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003446 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003447 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003448 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3449 // Remove these checks once both send and receive side assigns payload
3450 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003451 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003452 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003453 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003454 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003455 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003456 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003457 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003458 EXPECT_EQ(111, codec.id);
3459 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3460 EXPECT_EQ("10", codec.params.find("minptime")->second);
3461 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3462 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003463 }
3464 }
stefan658910c2015-09-03 05:48:32 -07003465}
3466
3467// Tests that VoE supports at least 32 channels
3468TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003469 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003470 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003471 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003472 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003473 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003474 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003475 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003476 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003477 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003478 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003479
3480 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003481 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003482 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003483 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3484 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003485 if (!channel)
3486 break;
stefan658910c2015-09-03 05:48:32 -07003487 channels[num_channels++] = channel;
3488 }
3489
Mirko Bonadeif859e552018-05-30 15:31:29 +02003490 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003491 EXPECT_EQ(expected, num_channels);
3492
3493 while (num_channels > 0) {
3494 delete channels[--num_channels];
3495 }
stefan658910c2015-09-03 05:48:32 -07003496}
3497
3498// Test that we set our preferred codecs properly.
3499TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003500 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3501 // - Check that our builtin codecs are usable by Channel.
3502 // - The codecs provided by the engine is usable by Channel.
3503 // It does not check that the codecs in the RecvParameters are actually
3504 // what we sent in - though it's probably reasonable to expect so, if
3505 // SetRecvParameters returns true.
3506 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003507 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003508 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003509 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003510 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003511 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003512 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003513 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003514 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003515 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003516 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003517 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3518 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003519 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003520 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003521 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003522}
ossu9def8002017-02-09 05:14:32 -08003523
3524TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3525 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003526 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3527 {48000, 2, 16000, 10000, 20000}};
3528 spec1.info.allow_comfort_noise = false;
3529 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003530 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003531 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3532 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003533 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003534 specs.push_back(webrtc::AudioCodecSpec{
3535 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3536 {16000, 1, 13300}});
3537 specs.push_back(
3538 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3539 specs.push_back(
3540 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003541
ossueb1fde42017-05-02 06:46:30 -07003542 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3543 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3544 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003545 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003546 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003547 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003548 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003549
peaha9cc40b2017-06-29 08:32:09 -07003550 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003551 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003552 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003553 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003554 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003555 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003556 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003557
3558 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3559 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003560 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3561 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3562 if (codecs.size() > index)
3563 return codecs[index];
3564 return missing_codec;
3565 };
ossu9def8002017-02-09 05:14:32 -08003566
3567 // Ensure the general codecs are generated first and in order.
3568 for (size_t i = 0; i != specs.size(); ++i) {
3569 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3570 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3571 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3572 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3573 }
3574
3575 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003576 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003577 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3578 for (size_t i = 0; i != codecs.size(); ++i) {
3579 const cricket::AudioCodec& codec = codecs[i];
3580 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3581 codec.clockrate == format.clockrate_hz &&
3582 codec.channels == format.num_channels) {
3583 return rtc::checked_cast<int>(i);
3584 }
3585 }
3586 return -1;
3587 };
ossu9def8002017-02-09 05:14:32 -08003588
3589 // Ensure all supplementary codecs are generated last. Their internal ordering
3590 // is not important.
3591 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3592 const int num_specs = static_cast<int>(specs.size());
3593 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3594 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3595 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3596 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3597 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3598 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3599 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3600}