blob: e24f18524a4423c7b1376fdb06f22b13ca21f78e [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
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080017#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "call/call.h"
19#include "logging/rtc_event_log/rtc_event_log.h"
20#include "media/base/fakemediaengine.h"
21#include "media/base/fakenetworkinterface.h"
22#include "media/base/fakertp.h"
23#include "media/base/mediaconstants.h"
24#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/webrtcvoiceengine.h"
26#include "modules/audio_device/include/mock_audio_device.h"
27#include "modules/audio_processing/include/mock_audio_processing.h"
28#include "pc/channel.h"
29#include "rtc_base/arraysize.h"
30#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010031#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/scoped_ref_ptr.h"
33#include "test/field_trial.h"
34#include "test/gtest.h"
35#include "test/mock_audio_decoder_factory.h"
36#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010040using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070041using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070042using testing::ReturnPointee;
43using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070044using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000045
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020046namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010047using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048
solenberg418b7d32017-06-13 00:38:27 -070049constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070050
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
52const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070053const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
55const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
57const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020058const cricket::AudioCodec kTelephoneEventCodec1(106,
59 "telephone-event",
60 8000,
61 0,
62 1);
63const cricket::AudioCodec kTelephoneEventCodec2(107,
64 "telephone-event",
65 32000,
66 0,
67 1);
solenberg2779bab2016-11-17 04:45:19 -080068
solenberg2100c0b2017-03-01 11:29:29 -080069const uint32_t kSsrc0 = 0;
70const uint32_t kSsrc1 = 1;
71const uint32_t kSsrcX = 0x99;
72const uint32_t kSsrcY = 0x17;
73const uint32_t kSsrcZ = 0x42;
74const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020075const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076
solenberg971cab02016-06-14 10:02:41 -070077constexpr int kRtpHistoryMs = 5000;
78
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010079constexpr webrtc::GainControl::Mode kDefaultAgcMode =
80#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
81 webrtc::GainControl::kFixedDigital;
82#else
83 webrtc::GainControl::kAdaptiveAnalog;
84#endif
85
86constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
87 webrtc::NoiseSuppression::kHigh;
88
solenberg9a5f032222017-03-15 06:14:12 -070089void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
90 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010091
92 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010093 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010094 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010095 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070096#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020097 EXPECT_CALL(
98 *adm, SetPlayoutDevice(
99 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
100 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
101 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700102#else
103 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
104#endif // #if defined(WEBRTC_WIN)
105 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
106 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
107 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100108#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200109 EXPECT_CALL(
110 *adm, SetRecordingDevice(
111 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
112 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
113 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114#else
115 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
116#endif // #if defined(WEBRTC_WIN)
117 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
118 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
119 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700120 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
122 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100123
124 // Teardown.
125 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
127 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
128 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200129 EXPECT_CALL(*adm, Release())
130 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100131 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700132}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200133} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134
solenbergff976312016-03-30 23:28:51 -0700135// Tests that our stub library "works".
136TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700137 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700138 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700139 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
140 new rtc::RefCountedObject<
141 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700142 webrtc::AudioProcessing::Config apm_config;
143 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
144 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700146 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700147 {
ossuc54071d2016-08-17 02:45:41 -0700148 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700149 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100150 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700151 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700152 }
solenbergff976312016-03-30 23:28:51 -0700153}
154
deadbeef884f5852016-01-15 09:20:04 -0800155class FakeAudioSink : public webrtc::AudioSinkInterface {
156 public:
157 void OnData(const Data& audio) override {}
158};
159
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800160class FakeAudioSource : public cricket::AudioSource {
161 void SetSink(Sink* sink) override {}
162};
163
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164class WebRtcVoiceEngineTestFake : public testing::Test {
165 public:
stefanba4c0e42016-02-04 04:12:24 -0800166 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
167
168 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700169 : apm_(new rtc::RefCountedObject<
170 StrictMock<webrtc::test::MockAudioProcessing>>()),
171 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700172 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.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100184 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800185 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100186 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
187 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800188 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800190 // Init does not overwrite default AGC config.
191 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
192 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
193 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800194 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
195 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700196 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800197 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700198 // factories. Those tests should probably be moved elsewhere.
199 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
200 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100201 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100202 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700203 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200204 send_parameters_.codecs.push_back(kPcmuCodec);
205 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100206
solenberg76377c52017-02-21 00:54:31 -0800207 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200208 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800209 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700213 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700214 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700215 cricket::AudioOptions(),
216 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200217 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000218 }
solenberg8189b022016-06-14 12:13:00 -0700219
solenbergff976312016-03-30 23:28:51 -0700220 bool SetupRecvStream() {
221 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700222 return false;
223 }
solenberg2100c0b2017-03-01 11:29:29 -0800224 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700225 }
solenberg8189b022016-06-14 12:13:00 -0700226
solenbergff976312016-03-30 23:28:51 -0700227 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200228 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
229 }
230
231 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700232 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000233 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
Florent Castellidacec712018-05-24 16:24:21 +0200235 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800236 return false;
237 }
peaha9cc40b2017-06-29 08:32:09 -0700238 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800239 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
242 bool AddRecvStream(uint32_t ssrc) {
243 EXPECT_TRUE(channel_);
244 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
245 }
246
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700248 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700249 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800250 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
251 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700252 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800253 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700257 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Niels Möllere6933812018-11-05 13:01:41 +0100258 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 }
solenberg8189b022016-06-14 12:13:00 -0700260
Yves Gerey665174f2018-06-19 15:03:05 +0200261 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100263 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
264 const auto* send_stream = call_.GetAudioSendStream(ssrc);
265 EXPECT_TRUE(send_stream);
266 return *send_stream;
267 }
268
deadbeef884f5852016-01-15 09:20:04 -0800269 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
270 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
271 EXPECT_TRUE(recv_stream);
272 return *recv_stream;
273 }
274
solenberg3a941542015-11-16 07:34:50 -0800275 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800276 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800277 }
278
solenberg7add0582015-11-20 09:59:34 -0800279 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800280 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800281 }
282
solenberg059fb442016-10-26 05:12:24 -0700283 void SetSend(bool enable) {
284 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700285 if (enable) {
286 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
288 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700289 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700290 }
solenberg059fb442016-10-26 05:12:24 -0700291 channel_->SetSend(enable);
292 }
293
294 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700295 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700296 ASSERT_TRUE(channel_);
297 EXPECT_TRUE(channel_->SetSendParameters(params));
298 }
299
Yves Gerey665174f2018-06-19 15:03:05 +0200300 void SetAudioSend(uint32_t ssrc,
301 bool enable,
302 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700303 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700304 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700305 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700306 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700307 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700308 }
309 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700310 }
311
Yves Gerey665174f2018-06-19 15:03:05 +0200312 void TestInsertDtmf(uint32_t ssrc,
313 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800314 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700315 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700317 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200319 EXPECT_TRUE(
320 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700324 SetSendParameters(send_parameters_);
325 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800327 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800328 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700329 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331
332 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700333 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800334 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200335 EXPECT_TRUE(
336 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000337 }
338
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800340 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100342 // Test send.
343 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800344 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100345 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800346 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800347 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800348 EXPECT_EQ(codec.id, telephone_event.payload_type);
349 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100350 EXPECT_EQ(2, telephone_event.event_code);
351 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
353
Johannes Kron9190b822018-10-29 11:22:05 +0100354 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
355 // For a caller, the answer will be applied in set remote description
356 // where SetSendParameters() is called.
357 EXPECT_TRUE(SetupChannel());
358 EXPECT_TRUE(
359 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
360 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
361 SetSendParameters(send_parameters_);
362 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
363 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
364 }
365
366 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
367 // For a callee, the answer will be applied in set local description
368 // where SetExtmapAllowMixed() and AddSendStream() are called.
369 EXPECT_TRUE(SetupChannel());
370 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
371 EXPECT_TRUE(
372 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
373
374 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
375 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
376 }
377
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 // Test that send bandwidth is set correctly.
379 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000380 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
381 // |expected_result| is the expected result from SetMaxSendBandwidth().
382 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700383 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
384 int max_bitrate,
385 bool expected_result,
386 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200387 cricket::AudioSendParameters parameters;
388 parameters.codecs.push_back(codec);
389 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700390 if (expected_result) {
391 SetSendParameters(parameters);
392 } else {
393 EXPECT_FALSE(channel_->SetSendParameters(parameters));
394 }
solenberg2100c0b2017-03-01 11:29:29 -0800395 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000396 }
397
skvlade0d46372016-04-07 22:59:22 -0700398 // Sets the per-stream maximum bitrate limit for the specified SSRC.
399 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700400 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700401 EXPECT_EQ(1UL, parameters.encodings.size());
402
Oskar Sundbom78807582017-11-16 11:09:55 +0100403 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800404 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700405 }
406
solenberg059fb442016-10-26 05:12:24 -0700407 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700408 cricket::AudioSendParameters send_parameters;
409 send_parameters.codecs.push_back(codec);
410 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700411 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700412 }
413
ossu20a4b3f2017-04-27 02:08:52 -0700414 void CheckSendCodecBitrate(int32_t ssrc,
415 const char expected_name[],
416 int expected_bitrate) {
417 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
418 EXPECT_EQ(expected_name, spec->format.name);
419 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700420 }
421
Danil Chapovalov00c71832018-06-15 15:58:38 +0200422 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700423 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700424 }
425
Danil Chapovalov00c71832018-06-15 15:58:38 +0200426 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
427 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700428 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
429 }
430
skvlade0d46372016-04-07 22:59:22 -0700431 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
432 int global_max,
433 int stream_max,
434 bool expected_result,
435 int expected_codec_bitrate) {
436 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800437 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700438
439 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700440 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800441 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700442
443 // Verify that reading back the parameters gives results
444 // consistent with the Set() result.
445 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800446 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700447 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
448 EXPECT_EQ(expected_result ? stream_max : -1,
449 resulting_parameters.encodings[0].max_bitrate_bps);
450
451 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800452 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700453 }
454
stefan13f1a0a2016-11-30 07:22:58 -0800455 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
456 int expected_min_bitrate_bps,
457 const char* start_bitrate_kbps,
458 int expected_start_bitrate_bps,
459 const char* max_bitrate_kbps,
460 int expected_max_bitrate_bps) {
461 EXPECT_TRUE(SetupSendStream());
462 auto& codecs = send_parameters_.codecs;
463 codecs.clear();
464 codecs.push_back(kOpusCodec);
465 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
466 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
467 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100468 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
469 SetSdpBitrateParameters(
470 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
471 expected_min_bitrate_bps),
472 Field(&BitrateConstraints::start_bitrate_bps,
473 expected_start_bitrate_bps),
474 Field(&BitrateConstraints::max_bitrate_bps,
475 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800476
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100477 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800478 }
479
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000480 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700481 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000482
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000483 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000485
486 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700487 send_parameters_.extensions.push_back(
488 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700489 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200493 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());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000496
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000497 // Ensure extension is set properly.
498 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700499 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700500 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
502 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
503 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000504
solenberg7add0582015-11-20 09:59:34 -0800505 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200506 EXPECT_TRUE(
507 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800508 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
509 call_.GetAudioSendStream(kSsrcY));
510 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
511 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
514 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200515 send_parameters_.codecs.push_back(kPcmuCodec);
516 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700517 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800518 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
519 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000520 }
521
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000522 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700523 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000525 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000527
528 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700529 recv_parameters_.extensions.push_back(
530 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800531 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800532 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000533
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000534 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800535 recv_parameters_.extensions.clear();
536 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800537 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000538
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000539 // Ensure extension is set properly.
540 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700541 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800542 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800543 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
544 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
545 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000546
solenberg7add0582015-11-20 09:59:34 -0800547 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800548 EXPECT_TRUE(AddRecvStream(kSsrcY));
549 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
550 call_.GetAudioReceiveStream(kSsrcY));
551 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
552 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
553 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000554
555 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800556 recv_parameters_.extensions.clear();
557 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800558 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
559 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000560 }
561
solenberg85a04962015-10-27 03:35:21 -0700562 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
563 webrtc::AudioSendStream::Stats stats;
564 stats.local_ssrc = 12;
565 stats.bytes_sent = 345;
566 stats.packets_sent = 678;
567 stats.packets_lost = 9012;
568 stats.fraction_lost = 34.56f;
569 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100570 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700571 stats.ext_seqnum = 789;
572 stats.jitter_ms = 12;
573 stats.rtt_ms = 345;
574 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100575 stats.apm_statistics.delay_median_ms = 234;
576 stats.apm_statistics.delay_standard_deviation_ms = 567;
577 stats.apm_statistics.echo_return_loss = 890;
578 stats.apm_statistics.echo_return_loss_enhancement = 1234;
579 stats.apm_statistics.residual_echo_likelihood = 0.432f;
580 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100581 stats.ana_statistics.bitrate_action_counter = 321;
582 stats.ana_statistics.channel_action_counter = 432;
583 stats.ana_statistics.dtx_action_counter = 543;
584 stats.ana_statistics.fec_action_counter = 654;
585 stats.ana_statistics.frame_length_increase_counter = 765;
586 stats.ana_statistics.frame_length_decrease_counter = 876;
587 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700588 stats.typing_noise_detected = true;
589 return stats;
590 }
591 void SetAudioSendStreamStats() {
592 for (auto* s : call_.GetAudioSendStreams()) {
593 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200594 }
solenberg85a04962015-10-27 03:35:21 -0700595 }
solenberg566ef242015-11-06 15:34:49 -0800596 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
597 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700598 const auto stats = GetAudioSendStreamStats();
599 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
600 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
601 EXPECT_EQ(info.packets_sent, stats.packets_sent);
602 EXPECT_EQ(info.packets_lost, stats.packets_lost);
603 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
604 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800605 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700606 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
607 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
608 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
609 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100610 EXPECT_EQ(info.apm_statistics.delay_median_ms,
611 stats.apm_statistics.delay_median_ms);
612 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
613 stats.apm_statistics.delay_standard_deviation_ms);
614 EXPECT_EQ(info.apm_statistics.echo_return_loss,
615 stats.apm_statistics.echo_return_loss);
616 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
617 stats.apm_statistics.echo_return_loss_enhancement);
618 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
619 stats.apm_statistics.residual_echo_likelihood);
620 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
621 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700622 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
623 stats.ana_statistics.bitrate_action_counter);
624 EXPECT_EQ(info.ana_statistics.channel_action_counter,
625 stats.ana_statistics.channel_action_counter);
626 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
627 stats.ana_statistics.dtx_action_counter);
628 EXPECT_EQ(info.ana_statistics.fec_action_counter,
629 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700630 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
631 stats.ana_statistics.frame_length_increase_counter);
632 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
633 stats.ana_statistics.frame_length_decrease_counter);
634 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
635 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800636 EXPECT_EQ(info.typing_noise_detected,
637 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700638 }
639
640 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
641 webrtc::AudioReceiveStream::Stats stats;
642 stats.remote_ssrc = 123;
643 stats.bytes_rcvd = 456;
644 stats.packets_rcvd = 768;
645 stats.packets_lost = 101;
646 stats.fraction_lost = 23.45f;
647 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100648 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700649 stats.ext_seqnum = 678;
650 stats.jitter_ms = 901;
651 stats.jitter_buffer_ms = 234;
652 stats.jitter_buffer_preferred_ms = 567;
653 stats.delay_estimate_ms = 890;
654 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700655 stats.total_samples_received = 5678901;
656 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200657 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200658 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700659 stats.expand_rate = 5.67f;
660 stats.speech_expand_rate = 8.90f;
661 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200662 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.accelerate_rate = 4.56f;
664 stats.preemptive_expand_rate = 7.89f;
665 stats.decoding_calls_to_silence_generator = 12;
666 stats.decoding_calls_to_neteq = 345;
667 stats.decoding_normal = 67890;
668 stats.decoding_plc = 1234;
669 stats.decoding_cng = 5678;
670 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700671 stats.decoding_muted_output = 3456;
672 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200673 return stats;
674 }
675 void SetAudioReceiveStreamStats() {
676 for (auto* s : call_.GetAudioReceiveStreams()) {
677 s->SetStats(GetAudioReceiveStreamStats());
678 }
679 }
680 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700681 const auto stats = GetAudioReceiveStreamStats();
682 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
683 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200684 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
685 stats.packets_rcvd);
686 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
687 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700688 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
689 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800690 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
692 stats.ext_seqnum);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
695 stats.jitter_buffer_ms);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700697 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
699 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700700 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700701 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
702 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200703 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200704 EXPECT_EQ(info.jitter_buffer_delay_seconds,
705 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700706 EXPECT_EQ(info.expand_rate, stats.expand_rate);
707 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
708 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200709 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700710 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
711 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200712 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700713 stats.decoding_calls_to_silence_generator);
714 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
715 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
716 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
717 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
718 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700719 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700720 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200721 }
hbos1acfbd22016-11-17 23:43:29 -0800722 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
723 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
724 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
725 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
726 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
727 codec.ToCodecParameters());
728 }
729 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
730 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
731 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
732 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
733 codec.ToCodecParameters());
734 }
735 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200736
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200737 bool IsEchoCancellationEnabled() {
738 return engine_->GetApmConfigForTest().echo_canceller.enabled;
739 }
740
peah8271d042016-11-22 07:24:52 -0800741 bool IsHighPassFilterEnabled() {
742 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
743 }
744
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700746 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700747 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800748 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800749 webrtc::test::MockNoiseSuppression& apm_ns_;
750 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200751 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700752 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700753 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200754 cricket::AudioSendParameters send_parameters_;
755 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800756 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700757 webrtc::AudioProcessing::Config apm_config_;
758
stefanba4c0e42016-02-04 04:12:24 -0800759 private:
760 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761};
762
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763// Tests that we can create and destroy a channel.
764TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700765 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766}
767
solenberg31fec402016-05-06 02:13:12 -0700768// Test that we can add a send stream and that it has the correct defaults.
769TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
770 EXPECT_TRUE(SetupChannel());
771 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800772 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
773 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
774 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700775 EXPECT_EQ("", config.rtp.c_name);
776 EXPECT_EQ(0u, config.rtp.extensions.size());
777 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
778 config.send_transport);
779}
780
781// Test that we can add a receive stream and that it has the correct defaults.
782TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
783 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800784 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700785 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800786 GetRecvStreamConfig(kSsrcX);
787 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700788 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
789 EXPECT_FALSE(config.rtp.transport_cc);
790 EXPECT_EQ(0u, config.rtp.extensions.size());
791 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
792 config.rtcp_send_transport);
793 EXPECT_EQ("", config.sync_group);
794}
795
stefanba4c0e42016-02-04 04:12:24 -0800796TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700797 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800798 bool opus_found = false;
799 for (cricket::AudioCodec codec : codecs) {
800 if (codec.name == "opus") {
801 EXPECT_TRUE(HasTransportCc(codec));
802 opus_found = true;
803 }
804 }
805 EXPECT_TRUE(opus_found);
806}
807
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808// Test that we set our inbound codecs properly, including changing PT.
809TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700810 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200811 cricket::AudioRecvParameters parameters;
812 parameters.codecs.push_back(kIsacCodec);
813 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800814 parameters.codecs.push_back(kTelephoneEventCodec1);
815 parameters.codecs.push_back(kTelephoneEventCodec2);
816 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200817 parameters.codecs[2].id = 126;
818 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800819 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700820 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
821 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
822 {{0, {"PCMU", 8000, 1}},
823 {106, {"ISAC", 16000, 1}},
824 {126, {"telephone-event", 8000, 1}},
825 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826}
827
828// Test that we fail to set an unknown inbound codec.
829TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700830 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200831 cricket::AudioRecvParameters parameters;
832 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700833 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835}
836
837// Test that we fail if we have duplicate types in the inbound list.
838TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
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(kCn16000Codec);
843 parameters.codecs[1].id = kIsacCodec.id;
844 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847// Test that we can decode OPUS without stereo parameters.
848TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700849 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200850 cricket::AudioRecvParameters parameters;
851 parameters.codecs.push_back(kIsacCodec);
852 parameters.codecs.push_back(kPcmuCodec);
853 parameters.codecs.push_back(kOpusCodec);
854 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800855 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700856 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
857 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
858 {{0, {"PCMU", 8000, 1}},
859 {103, {"ISAC", 16000, 1}},
860 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000861}
862
863// Test that we can decode OPUS with stereo = 0.
864TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700865 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200866 cricket::AudioRecvParameters parameters;
867 parameters.codecs.push_back(kIsacCodec);
868 parameters.codecs.push_back(kPcmuCodec);
869 parameters.codecs.push_back(kOpusCodec);
870 parameters.codecs[2].params["stereo"] = "0";
871 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800872 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700873 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
874 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
875 {{0, {"PCMU", 8000, 1}},
876 {103, {"ISAC", 16000, 1}},
877 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878}
879
880// Test that we can decode OPUS with stereo = 1.
881TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700882 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200883 cricket::AudioRecvParameters parameters;
884 parameters.codecs.push_back(kIsacCodec);
885 parameters.codecs.push_back(kPcmuCodec);
886 parameters.codecs.push_back(kOpusCodec);
887 parameters.codecs[2].params["stereo"] = "1";
888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800889 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700890 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
891 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
892 {{0, {"PCMU", 8000, 1}},
893 {103, {"ISAC", 16000, 1}},
894 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895}
896
897// Test that changes to recv codecs are applied to all streams.
898TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700899 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200900 cricket::AudioRecvParameters parameters;
901 parameters.codecs.push_back(kIsacCodec);
902 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800903 parameters.codecs.push_back(kTelephoneEventCodec1);
904 parameters.codecs.push_back(kTelephoneEventCodec2);
905 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200906 parameters.codecs[2].id = 126;
907 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700908 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
909 EXPECT_TRUE(AddRecvStream(ssrc));
910 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
911 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
912 {{0, {"PCMU", 8000, 1}},
913 {106, {"ISAC", 16000, 1}},
914 {126, {"telephone-event", 8000, 1}},
915 {107, {"telephone-event", 32000, 1}}})));
916 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917}
918
919TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700920 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 cricket::AudioRecvParameters parameters;
922 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800923 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925
solenberg2100c0b2017-03-01 11:29:29 -0800926 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200927 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800928 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929}
930
931// Test that we can apply the same set of codecs again while playing.
932TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700933 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200934 cricket::AudioRecvParameters parameters;
935 parameters.codecs.push_back(kIsacCodec);
936 parameters.codecs.push_back(kCn16000Codec);
937 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700938 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
deadbeefcb383672017-04-26 16:28:42 -0700941 // Remapping a payload type to a different codec should fail.
942 parameters.codecs[0] = kOpusCodec;
943 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200944 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800945 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946}
947
948// Test that we can add a codec while playing.
949TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700950 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200951 cricket::AudioRecvParameters parameters;
952 parameters.codecs.push_back(kIsacCodec);
953 parameters.codecs.push_back(kCn16000Codec);
954 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700955 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 parameters.codecs.push_back(kOpusCodec);
958 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800959 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960}
961
deadbeefcb383672017-04-26 16:28:42 -0700962// Test that we accept adding the same codec with a different payload type.
963// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
964TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
965 EXPECT_TRUE(SetupRecvStream());
966 cricket::AudioRecvParameters parameters;
967 parameters.codecs.push_back(kIsacCodec);
968 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
969
970 ++parameters.codecs[0].id;
971 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
972}
973
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700975 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000977 // Test that when autobw is enabled, bitrate is kept as the default
978 // value. autobw is enabled for the following tests because the target
979 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980
981 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700982 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983
984 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700985 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986
ossu20a4b3f2017-04-27 02:08:52 -0700987 // opus, default bitrate == 32000 in mono.
988 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989}
990
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000991TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700992 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000993
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700995 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
996 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700997 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001000 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1001 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1002 // Rates above the max (510000) should be capped.
1003 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004}
1005
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001006TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001007 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001008
1009 // Test that we can only set a maximum bitrate for a fixed-rate codec
1010 // if it's bigger than the fixed rate.
1011
1012 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001013 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1014 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1015 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1016 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1017 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1018 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1019 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001020}
1021
1022TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001023 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001024 const int kDesiredBitrate = 128000;
1025 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001026 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001027 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001028 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001029
Yves Gerey665174f2018-06-19 15:03:05 +02001030 EXPECT_TRUE(
1031 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001032
solenberg2100c0b2017-03-01 11:29:29 -08001033 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001034}
1035
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001036// Test that bitrate cannot be set for CBR codecs.
1037// Bitrate is ignored if it is higher than the fixed bitrate.
1038// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001039TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001040 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001041
1042 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001043 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001044 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045
1046 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001047 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001048 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001049
1050 send_parameters_.max_bandwidth_bps = 128;
1051 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001052 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053}
1054
skvlade0d46372016-04-07 22:59:22 -07001055// Test that the per-stream bitrate limit and the global
1056// bitrate limit both apply.
1057TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1058 EXPECT_TRUE(SetupSendStream());
1059
ossu20a4b3f2017-04-27 02:08:52 -07001060 // opus, default bitrate == 32000.
1061 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001062 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1063 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1064 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1065
1066 // CBR codecs allow both maximums to exceed the bitrate.
1067 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1068 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1069 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1070 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1071
1072 // CBR codecs don't allow per stream maximums to be too low.
1073 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1074 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1075}
1076
1077// Test that an attempt to set RtpParameters for a stream that does not exist
1078// fails.
1079TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1080 EXPECT_TRUE(SetupChannel());
1081 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001082 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001083 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001084
1085 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001086 EXPECT_FALSE(
1087 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001088}
1089
1090TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001091 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001092 // This test verifies that setting RtpParameters succeeds only if
1093 // the structure contains exactly one encoding.
1094 // TODO(skvlad): Update this test when we start supporting setting parameters
1095 // for each encoding individually.
1096
1097 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001098 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001099 // Two or more encodings should result in failure.
1100 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001101 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001102 // Zero encodings should also fail.
1103 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001104 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001105}
1106
1107// Changing the SSRC through RtpParameters is not allowed.
1108TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1109 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001110 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001111 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001112 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001113}
1114
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001115// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001116// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001117TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1118 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001119 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001120 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001121 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001122 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001123 ASSERT_EQ(1u, parameters.encodings.size());
1124 ASSERT_TRUE(parameters.encodings[0].active);
1125 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001126 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001127 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001128
1129 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001130 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001131 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001132 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001133 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001134 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001135}
1136
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001137// Test that SetRtpSendParameters configures the correct encoding channel for
1138// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001139TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1140 SetupForMultiSendStream();
1141 // Create send streams.
1142 for (uint32_t ssrc : kSsrcs4) {
1143 EXPECT_TRUE(
1144 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1145 }
1146 // Configure one stream to be limited by the stream config, another to be
1147 // limited by the global max, and the third one with no per-stream limit
1148 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001149 SetGlobalMaxBitrate(kOpusCodec, 32000);
1150 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1151 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001152 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1153
ossu20a4b3f2017-04-27 02:08:52 -07001154 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1155 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1156 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001157
1158 // Remove the global cap; the streams should switch to their respective
1159 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001160 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001161 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1162 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1163 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001164}
1165
Tim Haloun648d28a2018-10-18 16:52:22 -07001166// RTCRtpEncodingParameters.network_priority must be one of a few values
1167// derived from the default priority, corresponding to very-low, low, medium,
1168// or high.
1169TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1170 EXPECT_TRUE(SetupSendStream());
1171 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1172 EXPECT_EQ(1UL, parameters.encodings.size());
1173 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1174 parameters.encodings[0].network_priority);
1175
1176 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1177 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1178 for (auto it : good_values) {
1179 parameters.encodings[0].network_priority = it;
1180 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1181 }
1182 for (auto it : bad_values) {
1183 parameters.encodings[0].network_priority = it;
1184 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1185 }
1186}
1187
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001188// Test that GetRtpSendParameters returns the currently configured codecs.
1189TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001190 EXPECT_TRUE(SetupSendStream());
1191 cricket::AudioSendParameters parameters;
1192 parameters.codecs.push_back(kIsacCodec);
1193 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001194 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001195
solenberg2100c0b2017-03-01 11:29:29 -08001196 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001197 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001198 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1199 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001200}
1201
Florent Castellidacec712018-05-24 16:24:21 +02001202// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1203TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1204 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1205 params.cname = "rtcpcname";
1206 EXPECT_TRUE(SetupSendStream(params));
1207
1208 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1209 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1210}
1211
Florent Castelliabe301f2018-06-12 18:33:49 +02001212TEST_F(WebRtcVoiceEngineTestFake,
1213 DetectRtpSendParameterHeaderExtensionsChange) {
1214 EXPECT_TRUE(SetupSendStream());
1215
1216 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1217 rtp_parameters.header_extensions.emplace_back();
1218
1219 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1220
1221 webrtc::RTCError result =
1222 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1223 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1224}
1225
deadbeefcb443432016-12-12 11:12:36 -08001226// Test that GetRtpSendParameters returns an SSRC.
1227TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1228 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001229 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001230 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001231 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001232}
1233
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001234// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001235TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001236 EXPECT_TRUE(SetupSendStream());
1237 cricket::AudioSendParameters parameters;
1238 parameters.codecs.push_back(kIsacCodec);
1239 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001240 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001241
solenberg2100c0b2017-03-01 11:29:29 -08001242 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001243
1244 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001245 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001246
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001247 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001248 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1249 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001250}
1251
minyuececec102017-03-27 13:04:25 -07001252// Test that max_bitrate_bps in send stream config gets updated correctly when
1253// SetRtpSendParameters is called.
1254TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1255 webrtc::test::ScopedFieldTrials override_field_trials(
1256 "WebRTC-Audio-SendSideBwe/Enabled/");
1257 EXPECT_TRUE(SetupSendStream());
1258 cricket::AudioSendParameters send_parameters;
1259 send_parameters.codecs.push_back(kOpusCodec);
1260 SetSendParameters(send_parameters);
1261
1262 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1263 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1264 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1265
1266 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001267 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001268 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001269
1270 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1271 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1272}
1273
Seth Hampson24722b32017-12-22 09:36:42 -08001274// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1275// a value <= 0, setting the parameters returns false.
1276TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1277 EXPECT_TRUE(SetupSendStream());
1278 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1279 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1280 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1281 rtp_parameters.encodings[0].bitrate_priority);
1282
1283 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001284 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001285 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001286 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001287}
1288
1289// Test that the bitrate_priority in the send stream config gets updated when
1290// SetRtpSendParameters is set for the VoiceMediaChannel.
1291TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1292 EXPECT_TRUE(SetupSendStream());
1293 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1294
1295 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1296 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1297 rtp_parameters.encodings[0].bitrate_priority);
1298 double new_bitrate_priority = 2.0;
1299 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001300 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001301
1302 // The priority should get set for both the audio channel's rtp parameters
1303 // and the audio send stream's audio config.
1304 EXPECT_EQ(
1305 new_bitrate_priority,
1306 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1307 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1308}
1309
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001310// Test that GetRtpReceiveParameters returns the currently configured codecs.
1311TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1312 EXPECT_TRUE(SetupRecvStream());
1313 cricket::AudioRecvParameters parameters;
1314 parameters.codecs.push_back(kIsacCodec);
1315 parameters.codecs.push_back(kPcmuCodec);
1316 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1317
1318 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001319 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001320 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1321 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1322 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1323}
1324
deadbeefcb443432016-12-12 11:12:36 -08001325// Test that GetRtpReceiveParameters returns an SSRC.
1326TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1327 EXPECT_TRUE(SetupRecvStream());
1328 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001329 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001330 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001331 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001332}
1333
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001334// Test that if we set/get parameters multiple times, we get the same results.
1335TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1336 EXPECT_TRUE(SetupRecvStream());
1337 cricket::AudioRecvParameters parameters;
1338 parameters.codecs.push_back(kIsacCodec);
1339 parameters.codecs.push_back(kPcmuCodec);
1340 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1341
1342 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001343 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001344
1345 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001346 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001347
1348 // ... And this shouldn't change the params returned by
1349 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001350 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1351 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001352}
1353
deadbeef3bc15102017-04-20 19:25:07 -07001354// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1355// aren't signaled. It should return an empty "RtpEncodingParameters" when
1356// configured to receive an unsignaled stream and no packets have been received
1357// yet, and start returning the SSRC once a packet has been received.
1358TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1359 ASSERT_TRUE(SetupChannel());
1360 // Call necessary methods to configure receiving a default stream as
1361 // soon as it arrives.
1362 cricket::AudioRecvParameters parameters;
1363 parameters.codecs.push_back(kIsacCodec);
1364 parameters.codecs.push_back(kPcmuCodec);
1365 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1366
1367 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1368 // stream. Should return nothing.
1369 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1370
1371 // Set a sink for an unsignaled stream.
1372 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1373 // Value of "0" means "unsignaled stream".
1374 channel_->SetRawAudioSink(0, std::move(fake_sink));
1375
1376 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1377 // in this method means "unsignaled stream".
1378 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1379 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1380 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1381
1382 // Receive PCMU packet (SSRC=1).
1383 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1384
1385 // The |ssrc| member should still be unset.
1386 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1387 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1388 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1389}
1390
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391// Test that we apply codecs properly.
1392TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001393 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 cricket::AudioSendParameters parameters;
1395 parameters.codecs.push_back(kIsacCodec);
1396 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001397 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001399 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001400 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001401 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1402 EXPECT_EQ(96, send_codec_spec.payload_type);
1403 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1404 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1405 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001406 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001407 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408}
1409
ossu20a4b3f2017-04-27 02:08:52 -07001410// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1411// AudioSendStream.
1412TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001413 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 cricket::AudioSendParameters parameters;
1415 parameters.codecs.push_back(kIsacCodec);
1416 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001417 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 parameters.codecs[0].id = 96;
1419 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001420 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001423 // Calling SetSendCodec again with same codec which is already set.
1424 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001427}
1428
ossu20a4b3f2017-04-27 02:08:52 -07001429// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1430// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001431
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001432// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kOpusCodec);
1437 parameters.codecs[0].bitrate = 0;
1438 parameters.codecs[0].clockrate = 50000;
1439 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440}
1441
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001442// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001444 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 cricket::AudioSendParameters parameters;
1446 parameters.codecs.push_back(kOpusCodec);
1447 parameters.codecs[0].bitrate = 0;
1448 parameters.codecs[0].channels = 0;
1449 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001450}
1451
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001452// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001454 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 cricket::AudioSendParameters parameters;
1456 parameters.codecs.push_back(kOpusCodec);
1457 parameters.codecs[0].bitrate = 0;
1458 parameters.codecs[0].channels = 0;
1459 parameters.codecs[0].params["stereo"] = "1";
1460 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
1463// Test that if channel is 1 for opus and there's no stereo, we fail.
1464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 0;
1469 parameters.codecs[0].channels = 1;
1470 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471}
1472
1473// Test that if channel is 1 for opus and stereo=0, we fail.
1474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].bitrate = 0;
1479 parameters.codecs[0].channels = 1;
1480 parameters.codecs[0].params["stereo"] = "0";
1481 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
1484// Test that if channel is 1 for opus and stereo=1, we fail.
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
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].channels = 1;
1491 parameters.codecs[0].params["stereo"] = "1";
1492 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
ossu20a4b3f2017-04-27 02:08:52 -07001495// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
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].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001501 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001502 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001503}
1504
ossu20a4b3f2017-04-27 02:08:52 -07001505// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001507 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001508 cricket::AudioSendParameters parameters;
1509 parameters.codecs.push_back(kOpusCodec);
1510 parameters.codecs[0].bitrate = 0;
1511 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001512 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001513 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001522 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001523 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001525 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001526
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001528 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001529 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001530}
1531
ossu20a4b3f2017-04-27 02:08:52 -07001532// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001534 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].bitrate = 0;
1538 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001540 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541}
1542
ossu20a4b3f2017-04-27 02:08:52 -07001543// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001549 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001551 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001552 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001553
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001555 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001556 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001557}
1558
ossu20a4b3f2017-04-27 02:08:52 -07001559// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001561 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001562 cricket::AudioSendParameters parameters;
1563 parameters.codecs.push_back(kOpusCodec);
1564 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001565 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001566 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1567 EXPECT_EQ(111, spec.payload_type);
1568 EXPECT_EQ(96000, spec.target_bitrate_bps);
1569 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001570 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001571 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572}
1573
ossu20a4b3f2017-04-27 02:08:52 -07001574// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001576 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 cricket::AudioSendParameters parameters;
1578 parameters.codecs.push_back(kOpusCodec);
1579 parameters.codecs[0].bitrate = 30000;
1580 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001581 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001582 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
ossu20a4b3f2017-04-27 02:08:52 -07001585// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001587 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 cricket::AudioSendParameters parameters;
1589 parameters.codecs.push_back(kOpusCodec);
1590 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001591 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001592 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
ossu20a4b3f2017-04-27 02:08:52 -07001595// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].bitrate = 30000;
1601 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001603 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001604}
1605
stefan13f1a0a2016-11-30 07:22:58 -08001606TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1607 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1608 200000);
1609}
1610
1611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1612 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1613}
1614
1615TEST_F(WebRtcVoiceEngineTestFake,
1616 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1617 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1618}
1619
1620TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1621 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1622}
1623
Yves Gerey665174f2018-06-19 15:03:05 +02001624TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001625 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1626 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001627 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001628 // Setting max bitrate should keep previous min bitrate
1629 // Setting max bitrate should not reset start bitrate.
1630 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1631 SetSdpBitrateParameters(
1632 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1633 Field(&BitrateConstraints::start_bitrate_bps, -1),
1634 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001635 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001636}
1637
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001638// Test that we can enable NACK with opus as caller.
1639TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001640 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001641 cricket::AudioSendParameters parameters;
1642 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001643 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1644 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001645 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648}
1649
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001650// Test that we can enable NACK with opus as callee.
1651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001652 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 cricket::AudioSendParameters parameters;
1654 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001655 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1656 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001657 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001659 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001661
Yves Gerey665174f2018-06-19 15:03:05 +02001662 EXPECT_TRUE(
1663 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001664 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001665}
1666
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667// Test that we can enable NACK on receive streams.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001670 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001673 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1674 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1676 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
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);
1679 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680}
1681
1682// Test that we can disable NACK.
1683TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001684 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 cricket::AudioSendParameters parameters;
1686 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001687 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1688 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001689 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001690 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001691
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 parameters.codecs.clear();
1693 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001695 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696}
1697
1698// Test that we can disable NACK on receive streams.
1699TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001700 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001701 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 cricket::AudioSendParameters parameters;
1703 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001704 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1705 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001706 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001707 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1708 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 parameters.codecs.clear();
1711 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001713 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1714 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715}
1716
1717// Test that NACK is enabled on a new receive stream.
1718TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001719 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 cricket::AudioSendParameters parameters;
1721 parameters.codecs.push_back(kIsacCodec);
1722 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001723 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1724 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001726 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727
solenberg2100c0b2017-03-01 11:29:29 -08001728 EXPECT_TRUE(AddRecvStream(kSsrcY));
1729 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1730 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1731 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732}
1733
stefanba4c0e42016-02-04 04:12:24 -08001734TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001735 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001736 cricket::AudioSendParameters send_parameters;
1737 send_parameters.codecs.push_back(kOpusCodec);
1738 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001740
1741 cricket::AudioRecvParameters recv_parameters;
1742 recv_parameters.codecs.push_back(kIsacCodec);
1743 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001744 EXPECT_TRUE(AddRecvStream(kSsrcX));
1745 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001746 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001747 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001748
ossudedfd282016-06-14 07:12:39 -07001749 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001751 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001752 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001753 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001754}
1755
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001756// Test that we can switch back and forth between Opus and ISAC with CN.
1757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001758 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001759
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 cricket::AudioSendParameters opus_parameters;
1761 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(opus_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(111, spec.payload_type);
1766 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001767 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001769 cricket::AudioSendParameters isac_parameters;
1770 isac_parameters.codecs.push_back(kIsacCodec);
1771 isac_parameters.codecs.push_back(kCn16000Codec);
1772 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001773 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001774 {
ossu20a4b3f2017-04-27 02:08:52 -07001775 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1776 EXPECT_EQ(103, spec.payload_type);
1777 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001778 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(opus_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(111, spec.payload_type);
1784 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001785 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786}
1787
1788// Test that we handle various ways of specifying bitrate.
1789TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001790 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 cricket::AudioSendParameters parameters;
1792 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001794 {
ossu20a4b3f2017-04-27 02:08:52 -07001795 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1796 EXPECT_EQ(103, spec.payload_type);
1797 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1798 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001799 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800
Yves Gerey665174f2018-06-19 15:03:05 +02001801 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001803 {
ossu20a4b3f2017-04-27 02:08:52 -07001804 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1805 EXPECT_EQ(103, spec.payload_type);
1806 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1807 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001808 }
Yves Gerey665174f2018-06-19 15:03:05 +02001809 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001810 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001811 {
ossu20a4b3f2017-04-27 02:08:52 -07001812 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1813 EXPECT_EQ(103, spec.payload_type);
1814 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1815 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001816 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817
Yves Gerey665174f2018-06-19 15:03:05 +02001818 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001819 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001820 {
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_EQ(0, spec.payload_type);
1823 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1824 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001825 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001826
Yves Gerey665174f2018-06-19 15:03:05 +02001827 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001829 {
ossu20a4b3f2017-04-27 02:08:52 -07001830 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1831 EXPECT_EQ(0, spec.payload_type);
1832 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1833 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001834 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001837 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001838 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001839 {
ossu20a4b3f2017-04-27 02:08:52 -07001840 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1841 EXPECT_EQ(111, spec.payload_type);
1842 EXPECT_STREQ("opus", spec.format.name.c_str());
1843 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001844 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001845}
1846
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001847// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001848TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001849 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001850 cricket::AudioSendParameters parameters;
1851 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001852}
1853
1854// Test that we can set send codecs even with telephone-event codec as the first
1855// one on the list.
1856TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001859 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 parameters.codecs.push_back(kIsacCodec);
1861 parameters.codecs.push_back(kPcmuCodec);
1862 parameters.codecs[0].id = 98; // DTMF
1863 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001865 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1866 EXPECT_EQ(96, spec.payload_type);
1867 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001868 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001869 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001870}
1871
Harald Alvestranda1f66612018-02-21 11:24:23 +01001872// Test that CanInsertDtmf() is governed by the send flag
1873TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1874 EXPECT_TRUE(SetupSendStream());
1875 cricket::AudioSendParameters parameters;
1876 parameters.codecs.push_back(kTelephoneEventCodec1);
1877 parameters.codecs.push_back(kPcmuCodec);
1878 parameters.codecs[0].id = 98; // DTMF
1879 parameters.codecs[1].id = 96;
1880 SetSendParameters(parameters);
1881 EXPECT_FALSE(channel_->CanInsertDtmf());
1882 SetSend(true);
1883 EXPECT_TRUE(channel_->CanInsertDtmf());
1884 SetSend(false);
1885 EXPECT_FALSE(channel_->CanInsertDtmf());
1886}
1887
solenberg31642aa2016-03-14 08:00:37 -07001888// Test that payload type range is limited for telephone-event codec.
1889TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001890 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001891 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001892 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001893 parameters.codecs.push_back(kIsacCodec);
1894 parameters.codecs[0].id = 0; // DTMF
1895 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001896 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001897 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001898 EXPECT_TRUE(channel_->CanInsertDtmf());
1899 parameters.codecs[0].id = 128; // DTMF
1900 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1901 EXPECT_FALSE(channel_->CanInsertDtmf());
1902 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001903 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001904 EXPECT_TRUE(channel_->CanInsertDtmf());
1905 parameters.codecs[0].id = -1; // DTMF
1906 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1907 EXPECT_FALSE(channel_->CanInsertDtmf());
1908}
1909
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001910// Test that we can set send codecs even with CN codec as the first
1911// one on the list.
1912TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001913 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 cricket::AudioSendParameters parameters;
1915 parameters.codecs.push_back(kCn16000Codec);
1916 parameters.codecs.push_back(kIsacCodec);
1917 parameters.codecs.push_back(kPcmuCodec);
1918 parameters.codecs[0].id = 98; // wideband CN
1919 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001920 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001921 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1922 EXPECT_EQ(96, send_codec_spec.payload_type);
1923 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001924 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925}
1926
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001927// Test that we set VAD and DTMF types correctly as caller.
1928TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001929 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 cricket::AudioSendParameters parameters;
1931 parameters.codecs.push_back(kIsacCodec);
1932 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001933 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 parameters.codecs.push_back(kCn16000Codec);
1935 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001936 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 parameters.codecs[0].id = 96;
1938 parameters.codecs[2].id = 97; // wideband CN
1939 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001940 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001941 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1942 EXPECT_EQ(96, send_codec_spec.payload_type);
1943 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001944 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001945 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001946 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001947 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948}
1949
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001950// Test that we set VAD and DTMF types correctly as callee.
1951TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001952 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 cricket::AudioSendParameters parameters;
1954 parameters.codecs.push_back(kIsacCodec);
1955 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001956 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 parameters.codecs.push_back(kCn16000Codec);
1958 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001959 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001960 parameters.codecs[0].id = 96;
1961 parameters.codecs[2].id = 97; // wideband CN
1962 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001963 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001964 EXPECT_TRUE(
1965 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001966
ossu20a4b3f2017-04-27 02:08:52 -07001967 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1968 EXPECT_EQ(96, send_codec_spec.payload_type);
1969 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001970 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001971 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001972 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001973 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001974}
1975
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976// Test that we only apply VAD if we have a CN codec that matches the
1977// send codec clockrate.
1978TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001979 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001981 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs.push_back(kIsacCodec);
1983 parameters.codecs.push_back(kCn16000Codec);
1984 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001986 {
ossu20a4b3f2017-04-27 02:08:52 -07001987 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1988 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001989 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001990 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001991 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001992 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001993 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001994 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001995 {
ossu20a4b3f2017-04-27 02:08:52 -07001996 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1997 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001998 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001999 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002000 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002002 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002003 {
ossu20a4b3f2017-04-27 02:08:52 -07002004 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2005 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002006 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002007 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002008 }
Brave Yao5225dd82015-03-26 07:39:19 +08002009 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002011 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002012 {
ossu20a4b3f2017-04-27 02:08:52 -07002013 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2014 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002015 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002016 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002017}
2018
2019// Test that we perform case-insensitive matching of codec names.
2020TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002021 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002022 cricket::AudioSendParameters parameters;
2023 parameters.codecs.push_back(kIsacCodec);
2024 parameters.codecs.push_back(kPcmuCodec);
2025 parameters.codecs.push_back(kCn16000Codec);
2026 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002027 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002028 parameters.codecs[0].name = "iSaC";
2029 parameters.codecs[0].id = 96;
2030 parameters.codecs[2].id = 97; // wideband CN
2031 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002032 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002033 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2034 EXPECT_EQ(96, send_codec_spec.payload_type);
2035 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002036 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002037 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002038 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002039 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002040}
2041
stefanba4c0e42016-02-04 04:12:24 -08002042class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2043 public:
2044 WebRtcVoiceEngineWithSendSideBweTest()
2045 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2046};
2047
2048TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2049 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002050 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002051 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002052 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2053 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2054 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002055 extension.id);
2056 return;
2057 }
2058 }
2059 FAIL() << "Transport sequence number extension not in header-extension list.";
2060}
2061
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002062// Test support for audio level header extension.
2063TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002064 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002065}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002066TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002067 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002068}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002069
solenbergd4adce42016-11-17 06:26:52 -08002070// Test support for transport sequence number header extension.
2071TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2072 TestSetSendRtpHeaderExtensions(
2073 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002074}
solenbergd4adce42016-11-17 06:26:52 -08002075TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2076 TestSetRecvRtpHeaderExtensions(
2077 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002078}
2079
solenberg1ac56142015-10-13 03:58:19 -07002080// Test that we can create a channel and start sending on it.
2081TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002082 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(send_parameters_);
2084 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002085 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002086 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002087 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002088}
2089
2090// Test that a channel will send if and only if it has a source and is enabled
2091// for sending.
2092TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002093 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002094 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002095 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002096 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2098 SetAudioSend(kSsrcX, true, &fake_source_);
2099 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2100 SetAudioSend(kSsrcX, true, nullptr);
2101 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002102}
2103
solenberg94218532016-06-16 10:53:22 -07002104// Test that a channel is muted/unmuted.
2105TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2106 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002107 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002108 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2109 SetAudioSend(kSsrcX, true, nullptr);
2110 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2111 SetAudioSend(kSsrcX, false, nullptr);
2112 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002113}
2114
solenberg6d6e7c52016-04-13 09:07:30 -07002115// Test that SetSendParameters() does not alter a stream's send state.
2116TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2117 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002118 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002119
2120 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002121 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002122 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002123
2124 // Changing RTP header extensions will recreate the AudioSendStream.
2125 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002126 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002127 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002128 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002129
2130 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002131 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002132 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002133
2134 // Changing RTP header extensions will recreate the AudioSendStream.
2135 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002136 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002137 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002138}
2139
solenberg1ac56142015-10-13 03:58:19 -07002140// Test that we can create a channel and start playing out on it.
2141TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002142 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002143 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002144 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002145 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002146 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002147 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148}
2149
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150// Test that we can add and remove send streams.
2151TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2152 SetupForMultiSendStream();
2153
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002155 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156
solenbergc96df772015-10-21 13:01:53 -07002157 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002158 EXPECT_TRUE(
2159 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002160 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002162 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
tfarina5237aaf2015-11-10 23:44:30 -08002164 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165
solenbergc96df772015-10-21 13:01:53 -07002166 // Delete the send streams.
2167 for (uint32_t ssrc : kSsrcs4) {
2168 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002169 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002170 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002171 }
solenbergc96df772015-10-21 13:01:53 -07002172 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173}
2174
2175// Test SetSendCodecs correctly configure the codecs in all send streams.
2176TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2177 SetupForMultiSendStream();
2178
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002181 EXPECT_TRUE(
2182 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002185 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002186 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002187 parameters.codecs.push_back(kIsacCodec);
2188 parameters.codecs.push_back(kCn16000Codec);
2189 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002190 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002191
2192 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002193 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002194 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2195 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002196 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2197 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002198 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002199 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002200 }
2201
minyue7a973442016-10-20 03:27:12 -07002202 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002203 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002204 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002205 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002206 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2207 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002208 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2209 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002210 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 }
2212}
2213
2214// Test we can SetSend on all send streams correctly.
2215TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2216 SetupForMultiSendStream();
2217
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002218 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002219 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002220 EXPECT_TRUE(
2221 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002222 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002223 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 }
2225
2226 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002227 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002228 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002229 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002230 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231 }
2232
2233 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002234 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002235 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002236 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002237 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002238 }
2239}
2240
2241// Test we can set the correct statistics on all send streams.
2242TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2243 SetupForMultiSendStream();
2244
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002245 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002246 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002247 EXPECT_TRUE(
2248 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002249 }
solenberg85a04962015-10-27 03:35:21 -07002250
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002251 // Create a receive stream to check that none of the send streams end up in
2252 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002253 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002254
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002255 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002256 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002257 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002258 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002259
solenberg85a04962015-10-27 03:35:21 -07002260 // Check stats for the added streams.
2261 {
2262 cricket::VoiceMediaInfo info;
2263 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002264
solenberg85a04962015-10-27 03:35:21 -07002265 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002266 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002267 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002268 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002269 }
hbos1acfbd22016-11-17 23:43:29 -08002270 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002271
2272 // We have added one receive stream. We should see empty stats.
2273 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002274 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002275 }
solenberg1ac56142015-10-13 03:58:19 -07002276
solenberg2100c0b2017-03-01 11:29:29 -08002277 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002278 {
2279 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002280 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002281 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002282 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002283 EXPECT_EQ(0u, info.receivers.size());
2284 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002285
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002286 // Deliver a new packet - a default receive stream should be created and we
2287 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002288 {
2289 cricket::VoiceMediaInfo info;
2290 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2291 SetAudioReceiveStreamStats();
2292 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002293 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002294 EXPECT_EQ(1u, info.receivers.size());
2295 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002296 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002297 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002298}
2299
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002300// Test that we can add and remove receive streams, and do proper send/playout.
2301// We can receive on multiple streams while sending one stream.
2302TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002303 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304
solenberg1ac56142015-10-13 03:58:19 -07002305 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002306 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002307 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002308
solenberg1ac56142015-10-13 03:58:19 -07002309 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002311 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002312 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002313
solenberg1ac56142015-10-13 03:58:19 -07002314 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002316
2317 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002318 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2319 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2320 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321
2322 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002323 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002324 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002325
2326 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002327 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002328 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2329 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002330
aleloi84ef6152016-08-04 05:28:21 -07002331 // Restart playout and make sure recv streams are played out.
2332 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002333 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2334 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002335
aleloi84ef6152016-08-04 05:28:21 -07002336 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002337 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2338 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002339}
2340
wu@webrtc.org97077a32013-10-25 21:18:33 +00002341TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002342 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002343 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2344 .Times(1)
2345 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002346 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2347 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002348 send_parameters_.options.tx_agc_target_dbov = 3;
2349 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2350 send_parameters_.options.tx_agc_limiter = true;
2351 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002352 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2353 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2354 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002355 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002356}
2357
minyue6b825df2016-10-31 04:08:32 -07002358TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2359 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002360 send_parameters_.options.audio_network_adaptor = true;
2361 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002362 SetSendParameters(send_parameters_);
2363 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002364 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002365}
2366
2367TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2368 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002369 send_parameters_.options.audio_network_adaptor = true;
2370 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002371 SetSendParameters(send_parameters_);
2372 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002373 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002374 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002375 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002376 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002377 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002378}
2379
2380TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2381 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002382 send_parameters_.options.audio_network_adaptor = true;
2383 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002384 SetSendParameters(send_parameters_);
2385 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002386 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002387 const int initial_num = call_.GetNumCreatedSendStreams();
2388 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002389 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002390 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2391 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002392 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002393 // AudioSendStream not expected to be recreated.
2394 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2395 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002396 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002397}
2398
michaelt6672b262017-01-11 10:17:59 -08002399class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2400 : public WebRtcVoiceEngineTestFake {
2401 public:
2402 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2403 : WebRtcVoiceEngineTestFake(
2404 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2405 "Enabled/") {}
2406};
2407
2408TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2409 EXPECT_TRUE(SetupSendStream());
2410 cricket::AudioSendParameters parameters;
2411 parameters.codecs.push_back(kOpusCodec);
2412 SetSendParameters(parameters);
2413 const int initial_num = call_.GetNumCreatedSendStreams();
2414 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2415
2416 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2417 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002418 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2419 constexpr int kMinOverheadBps =
2420 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002421
2422 constexpr int kOpusMinBitrateBps = 6000;
2423 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002424 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002425 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002426 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002427 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002428
Oskar Sundbom78807582017-11-16 11:09:55 +01002429 parameters.options.audio_network_adaptor = true;
2430 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002431 SetSendParameters(parameters);
2432
ossu11bfc532017-02-16 05:37:06 -08002433 constexpr int kMinOverheadWithAnaBps =
2434 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002435
2436 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002437 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002438
minyuececec102017-03-27 13:04:25 -07002439 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002440 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002441}
2442
minyuececec102017-03-27 13:04:25 -07002443// This test is similar to
2444// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2445// additional field trial.
2446TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2447 SetRtpSendParameterUpdatesMaxBitrate) {
2448 EXPECT_TRUE(SetupSendStream());
2449 cricket::AudioSendParameters send_parameters;
2450 send_parameters.codecs.push_back(kOpusCodec);
2451 SetSendParameters(send_parameters);
2452
2453 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2454 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2455 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2456
2457 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002458 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002459 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002460
2461 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2462#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2463 constexpr int kMinOverhead = 3333;
2464#else
2465 constexpr int kMinOverhead = 6666;
2466#endif
2467 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2468}
2469
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002471// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002473 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002474 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475}
2476
2477TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2478 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002479 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002480 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002481 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002482 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002483 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002484 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002485 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486
solenberg85a04962015-10-27 03:35:21 -07002487 // Check stats for the added streams.
2488 {
2489 cricket::VoiceMediaInfo info;
2490 EXPECT_EQ(true, channel_->GetStats(&info));
2491
2492 // We have added one send stream. We should see the stats we've set.
2493 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002494 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002495 // We have added one receive stream. We should see empty stats.
2496 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002497 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002498 }
solenberg1ac56142015-10-13 03:58:19 -07002499
solenberg566ef242015-11-06 15:34:49 -08002500 // Start sending - this affects some reported stats.
2501 {
2502 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002503 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002504 EXPECT_EQ(true, channel_->GetStats(&info));
2505 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002506 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002507 }
2508
solenberg2100c0b2017-03-01 11:29:29 -08002509 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002510 {
2511 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002512 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002513 EXPECT_EQ(true, channel_->GetStats(&info));
2514 EXPECT_EQ(1u, info.senders.size());
2515 EXPECT_EQ(0u, info.receivers.size());
2516 }
solenberg1ac56142015-10-13 03:58:19 -07002517
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002518 // Deliver a new packet - a default receive stream should be created and we
2519 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002520 {
2521 cricket::VoiceMediaInfo info;
2522 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2523 SetAudioReceiveStreamStats();
2524 EXPECT_EQ(true, channel_->GetStats(&info));
2525 EXPECT_EQ(1u, info.senders.size());
2526 EXPECT_EQ(1u, info.receivers.size());
2527 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002528 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002529 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002530}
2531
2532// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002533// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002535 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002536 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2537 EXPECT_TRUE(AddRecvStream(kSsrcY));
2538 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002539}
2540
2541// Test that the local SSRC is the same on sending and receiving channels if the
2542// receive channel is created before the send channel.
2543TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002544 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002545 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002546 EXPECT_TRUE(
2547 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002548 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2549 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550}
2551
2552// Test that we can properly receive packets.
2553TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002554 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002555 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002557
Yves Gerey665174f2018-06-19 15:03:05 +02002558 EXPECT_TRUE(
2559 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560}
2561
2562// Test that we can properly receive packets on multiple streams.
2563TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002564 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002565 const uint32_t ssrc1 = 1;
2566 const uint32_t ssrc2 = 2;
2567 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002568 EXPECT_TRUE(AddRecvStream(ssrc1));
2569 EXPECT_TRUE(AddRecvStream(ssrc2));
2570 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002571 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002572 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002573 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002574 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002575 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002576 }
mflodman3d7db262016-04-29 00:57:13 -07002577
2578 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2579 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2580 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2581
2582 EXPECT_EQ(s1.received_packets(), 0);
2583 EXPECT_EQ(s2.received_packets(), 0);
2584 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002585
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002586 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002587 EXPECT_EQ(s1.received_packets(), 0);
2588 EXPECT_EQ(s2.received_packets(), 0);
2589 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002590
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002591 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002592 EXPECT_EQ(s1.received_packets(), 1);
2593 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2594 EXPECT_EQ(s2.received_packets(), 0);
2595 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002596
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002597 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002598 EXPECT_EQ(s1.received_packets(), 1);
2599 EXPECT_EQ(s2.received_packets(), 1);
2600 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2601 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002602
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002603 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002604 EXPECT_EQ(s1.received_packets(), 1);
2605 EXPECT_EQ(s2.received_packets(), 1);
2606 EXPECT_EQ(s3.received_packets(), 1);
2607 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002608
mflodman3d7db262016-04-29 00:57:13 -07002609 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2610 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2611 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002612}
2613
solenberg2100c0b2017-03-01 11:29:29 -08002614// Test that receiving on an unsignaled stream works (a stream is created).
2615TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002616 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002617 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002618
solenberg7e63ef02015-11-20 00:19:43 -08002619 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002620
Mirko Bonadeif859e552018-05-30 15:31:29 +02002621 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002622 EXPECT_TRUE(
2623 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002624}
2625
Seth Hampson5897a6e2018-04-03 11:16:33 -07002626// Tests that when we add a stream without SSRCs, but contains a stream_id
2627// that it is stored and its stream id is later used when the first packet
2628// arrives to properly create a receive stream with a sync label.
2629TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2630 const char kSyncLabel[] = "sync_label";
2631 EXPECT_TRUE(SetupChannel());
2632 cricket::StreamParams unsignaled_stream;
2633 unsignaled_stream.set_stream_ids({kSyncLabel});
2634 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2635 // The stream shouldn't have been created at this point because it doesn't
2636 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002637 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002638
2639 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2640
Mirko Bonadeif859e552018-05-30 15:31:29 +02002641 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002642 EXPECT_TRUE(
2643 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2644 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2645
2646 // Removing the unsignaled stream clears the cached parameters. If a new
2647 // default unsignaled receive stream is created it will not have a sync group.
2648 channel_->RemoveRecvStream(0);
2649 channel_->RemoveRecvStream(kSsrc1);
2650
2651 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2652
Mirko Bonadeif859e552018-05-30 15:31:29 +02002653 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002654 EXPECT_TRUE(
2655 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2656 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2657}
2658
solenberg2100c0b2017-03-01 11:29:29 -08002659// Test that receiving N unsignaled stream works (streams will be created), and
2660// that packets are forwarded to them all.
2661TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002662 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002663 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002664 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2665
solenberg2100c0b2017-03-01 11:29:29 -08002666 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002667 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002668 rtc::SetBE32(&packet[8], ssrc);
2669 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002670
solenberg2100c0b2017-03-01 11:29:29 -08002671 // Verify we have one new stream for each loop iteration.
2672 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002673 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2674 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002675 }
mflodman3d7db262016-04-29 00:57:13 -07002676
solenberg2100c0b2017-03-01 11:29:29 -08002677 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002678 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002679 rtc::SetBE32(&packet[8], ssrc);
2680 DeliverPacket(packet, sizeof(packet));
2681
solenbergebb349d2017-03-13 05:46:15 -07002682 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002683 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2684 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2685 }
2686
2687 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2688 constexpr uint32_t kAnotherSsrc = 667;
2689 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002690 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002691
2692 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002693 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002694 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002695 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002696 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2697 EXPECT_EQ(2, streams[i]->received_packets());
2698 }
2699 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2700 EXPECT_EQ(1, streams[i]->received_packets());
2701 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002702 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002703}
2704
solenberg2100c0b2017-03-01 11:29:29 -08002705// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002706// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002707TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002708 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002709 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002710 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2711
2712 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002713 const uint32_t signaled_ssrc = 1;
2714 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002715 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002716 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002717 EXPECT_TRUE(
2718 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002719 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002720
2721 // Note that the first unknown SSRC cannot be 0, because we only support
2722 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002723 const uint32_t unsignaled_ssrc = 7011;
2724 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002725 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002726 EXPECT_TRUE(
2727 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002728 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002729
2730 DeliverPacket(packet, sizeof(packet));
2731 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2732
2733 rtc::SetBE32(&packet[8], signaled_ssrc);
2734 DeliverPacket(packet, sizeof(packet));
2735 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002736 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002737}
2738
solenberg4904fb62017-02-17 12:01:14 -08002739// Two tests to verify that adding a receive stream with the same SSRC as a
2740// previously added unsignaled stream will only recreate underlying stream
2741// objects if the stream parameters have changed.
2742TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2743 EXPECT_TRUE(SetupChannel());
2744
2745 // Spawn unsignaled stream with SSRC=1.
2746 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002747 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002748 EXPECT_TRUE(
2749 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002750
2751 // Verify that the underlying stream object in Call is not recreated when a
2752 // stream with SSRC=1 is added.
2753 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002754 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002755 int audio_receive_stream_id = streams.front()->id();
2756 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002757 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002758 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2759}
2760
2761TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2762 EXPECT_TRUE(SetupChannel());
2763
2764 // Spawn unsignaled stream with SSRC=1.
2765 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002766 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002767 EXPECT_TRUE(
2768 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002769
2770 // Verify that the underlying stream object in Call *is* recreated when a
2771 // stream with SSRC=1 is added, and which has changed stream parameters.
2772 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002773 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002774 int audio_receive_stream_id = streams.front()->id();
2775 cricket::StreamParams stream_params;
2776 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002777 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002778 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002779 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002780 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2781}
2782
solenberg1ac56142015-10-13 03:58:19 -07002783// Test that AddRecvStream creates new stream.
2784TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002785 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002786 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002787}
2788
2789// Test that after adding a recv stream, we do not decode more codecs than
2790// those previously passed into SetRecvCodecs.
2791TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002792 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002793 cricket::AudioRecvParameters parameters;
2794 parameters.codecs.push_back(kIsacCodec);
2795 parameters.codecs.push_back(kPcmuCodec);
2796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002798 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2799 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2800 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
2803// Test that we properly clean up any streams that were added, even if
2804// not explicitly removed.
2805TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002806 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002807 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002808 EXPECT_TRUE(AddRecvStream(1));
2809 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002810
Mirko Bonadeif859e552018-05-30 15:31:29 +02002811 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2812 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002813 delete channel_;
2814 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002815 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2816 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817}
2818
wu@webrtc.org78187522013-10-07 23:32:02 +00002819TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002820 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002821 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002822}
2823
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002824TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002825 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002826 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002827 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002828}
2829
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002830// Test the InsertDtmf on default send stream as caller.
2831TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002832 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002833}
2834
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002835// Test the InsertDtmf on default send stream as callee
2836TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002837 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002838}
2839
2840// Test the InsertDtmf on specified send stream as caller.
2841TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002842 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002843}
2844
2845// Test the InsertDtmf on specified send stream as callee.
2846TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002847 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848}
2849
Johannes Kron9190b822018-10-29 11:22:05 +01002850// Test propagation of extmap allow mixed setting.
2851TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2852 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2853}
2854TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2855 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2856}
2857TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2858 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2859}
2860TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2861 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2862}
2863
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002865 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002866 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002867 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2868 .Times(9)
2869 .WillRepeatedly(Return(false));
2870 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2871 .Times(4)
2872 .WillRepeatedly(Return(false));
2873 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2874 .Times(2)
2875 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002876
Mirko Bonadeif859e552018-05-30 15:31:29 +02002877 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002878 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
solenberg246b8172015-12-08 09:50:23 -08002880 // Nothing set in AudioOptions, so everything should be as default.
2881 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002882 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002883 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002884 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002885 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002886 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002887
2888 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002889 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002890 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002891 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892
2893 // Turn echo cancellation back on, with settings, and make sure
2894 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002895 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002896 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002897 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002899 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2900 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002901 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002902 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002903 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002904
2905 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002906 send_parameters_.options.delay_agnostic_aec = false;
2907 send_parameters_.options.extended_filter_aec = false;
2908 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002909 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002910 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002911
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002912 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002913 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002914 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002915 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002916
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002920 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002921 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002922 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002923
2924 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002925 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002926 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002927 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002928 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002929 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002931 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002932 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002933 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002934 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2936 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002937 send_parameters_.options.noise_suppression = false;
2938 send_parameters_.options.highpass_filter = false;
2939 send_parameters_.options.typing_detection = false;
2940 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002941 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002942 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002943 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002944
solenberg1ac56142015-10-13 03:58:19 -07002945 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002946 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002947 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002948 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002949 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2950 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002951 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002952 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953}
2954
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002955TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002956 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002957 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2958 .Times(8)
2959 .WillRepeatedly(Return(false));
2960 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2961 .Times(8)
2962 .WillRepeatedly(Return(false));
2963 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2964 .Times(8)
2965 .WillRepeatedly(Return(false));
2966 EXPECT_CALL(adm_, RecordingIsInitialized())
2967 .Times(2)
2968 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002969 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2970 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002971 webrtc::AudioProcessing::Config apm_config;
2972 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002973 .WillRepeatedly(ReturnPointee(&apm_config));
2974 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002975 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002976 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002977
kwiberg686a8ef2016-02-26 03:00:35 -08002978 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002979 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002980 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2981 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002982 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002983 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002984 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2985 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
2987 // Have to add a stream to make SetSend work.
2988 cricket::StreamParams stream1;
2989 stream1.ssrcs.push_back(1);
2990 channel1->AddSendStream(stream1);
2991 cricket::StreamParams stream2;
2992 stream2.ssrcs.push_back(2);
2993 channel2->AddSendStream(stream2);
2994
2995 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002996 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002997 parameters_options_all.options.echo_cancellation = true;
2998 parameters_options_all.options.auto_gain_control = true;
2999 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003002 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003003 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003004 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003005 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003007 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003008 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003009 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010
3011 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003012 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003013 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003014 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003015 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003016 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003017 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003018 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003019 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003020 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003021 expected_options.echo_cancellation = true;
3022 expected_options.auto_gain_control = true;
3023 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003024 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025
3026 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003027 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003028 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003029 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003030 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003031 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003032 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003033 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003034 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003035 expected_options.echo_cancellation = true;
3036 expected_options.auto_gain_control = false;
3037 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003038 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003039
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003040 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003041 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003042 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003043 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003044 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003045 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003047 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003048 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003049 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003050 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003051 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003052 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003054 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003055 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003056 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003057 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003058 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003059 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003060
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003061 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003062 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3063 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003064 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3065 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003066 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003067 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003068 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003069 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003070 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003071 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003072 expected_options.echo_cancellation = true;
3073 expected_options.auto_gain_control = false;
3074 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003075 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003076}
3077
wu@webrtc.orgde305012013-10-31 15:40:38 +00003078// This test verifies DSCP settings are properly applied on voice media channel.
3079TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003080 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003081 cricket::FakeNetworkInterface network_interface;
3082 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003083 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003084 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003085
peahb1c9d1d2017-07-25 15:45:24 -07003086 webrtc::AudioProcessing::Config apm_config;
3087 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003088 .WillRepeatedly(ReturnPointee(&apm_config));
3089 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003090 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003091 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003092
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003093 channel.reset(
3094 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3095 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003096 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003097 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3098 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3099
3100 config.enable_dscp = true;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003101 channel.reset(
3102 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3103 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003104 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003105 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3106
3107 // Create a send stream to configure
3108 EXPECT_TRUE(
3109 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3110 parameters = channel->GetRtpSendParameters(kSsrcZ);
3111 ASSERT_FALSE(parameters.encodings.empty());
3112
3113 // Various priorities map to various dscp values.
3114 parameters.encodings[0].network_priority = 4.0;
3115 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003116 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003117 parameters.encodings[0].network_priority = 0.5;
3118 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3119 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3120
3121 // A bad priority does not change the dscp value.
3122 parameters.encodings[0].network_priority = 0.0;
3123 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3124 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003125
Tim Haloun6ca98362018-09-17 17:06:08 -07003126 // Packets should also self-identify their dscp in PacketOptions.
3127 const uint8_t kData[10] = {0};
3128 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003129 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003130
nisse51542be2016-02-12 02:27:06 -08003131 // Verify that setting the option to false resets the
3132 // DiffServCodePoint.
3133 config.enable_dscp = false;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003134 channel.reset(
3135 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3136 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003137 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003138 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3139 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3140
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003141 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003142}
3143
solenberg4bac9c52015-10-09 02:32:53 -07003144TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003145 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003146 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003147 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003148 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003149 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003150 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3151 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3152 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003153}
3154
solenberg2100c0b2017-03-01 11:29:29 -08003155TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003156 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003157
3158 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003159 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003160 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3161
3162 // Should remember the volume "2" which will be set on new unsignaled streams,
3163 // and also set the gain to 2 on existing unsignaled streams.
3164 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3165 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3166
3167 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3168 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3169 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3170 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3171 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3172 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3173
3174 // Setting gain with SSRC=0 should affect all unsignaled streams.
3175 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003176 if (kMaxUnsignaledRecvStreams > 1) {
3177 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3178 }
solenberg2100c0b2017-03-01 11:29:29 -08003179 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3180
3181 // Setting gain on an individual stream affects only that.
3182 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003183 if (kMaxUnsignaledRecvStreams > 1) {
3184 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3185 }
solenberg2100c0b2017-03-01 11:29:29 -08003186 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003187}
3188
Seth Hampson845e8782018-03-02 11:34:10 -08003189TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003190 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003191 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003192
solenbergff976312016-03-30 23:28:51 -07003193 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003194 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003195 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003196 // Creating two channels to make sure that sync label is set properly for both
3197 // the default voice channel and following ones.
3198 EXPECT_TRUE(channel_->AddRecvStream(sp));
3199 sp.ssrcs[0] += 1;
3200 EXPECT_TRUE(channel_->AddRecvStream(sp));
3201
Mirko Bonadeif859e552018-05-30 15:31:29 +02003202 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003203 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003204 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003205 << "SyncGroup should be set based on stream id";
3206 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003207 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003208 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003209}
3210
solenberg3a941542015-11-16 07:34:50 -08003211// TODO(solenberg): Remove, once recv streams are configured through Call.
3212// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003213TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214 // Test that setting the header extensions results in the expected state
3215 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003216 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003217 ssrcs.push_back(223);
3218 ssrcs.push_back(224);
3219
solenbergff976312016-03-30 23:28:51 -07003220 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003221 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003222 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003223 EXPECT_TRUE(
3224 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003225 }
3226
Mirko Bonadeif859e552018-05-30 15:31:29 +02003227 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003228 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003229 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003230 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003231 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003232 }
3233
3234 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003235 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003236 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003237 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003238 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003239 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003240 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003241 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003242 EXPECT_NE(nullptr, s);
3243 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003244 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3245 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003246 for (const auto& s_ext : s_exts) {
3247 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003248 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003249 }
3250 }
3251 }
3252 }
3253
3254 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003255 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003256 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003257 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003259 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003260 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003261}
3262
3263TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3264 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003265 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003266 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003267 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003268 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3269 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003271 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272
solenbergff976312016-03-30 23:28:51 -07003273 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003274 cricket::WebRtcVoiceMediaChannel* media_channel =
3275 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003276 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003277 EXPECT_TRUE(media_channel->AddRecvStream(
3278 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3279
Mirko Bonadeif859e552018-05-30 15:31:29 +02003280 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003281 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003282 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003283 EXPECT_EQ(0, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003284 channel_->OnPacketReceived(&kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003285 EXPECT_EQ(1, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003286 channel_->OnRtcpReceived(&kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003287 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003288}
Minyue2013aec2015-05-13 14:14:42 +02003289
solenberg0a617e22015-10-20 15:49:38 -07003290// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003291// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003292TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003293 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003294 EXPECT_TRUE(AddRecvStream(kSsrcY));
3295 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003296 EXPECT_TRUE(
3297 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003298 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3299 EXPECT_TRUE(AddRecvStream(kSsrcW));
3300 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003301}
3302
solenberg7602aab2016-11-14 11:30:07 -08003303TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3304 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003305 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003306 EXPECT_TRUE(
3307 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003308 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3309 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3310 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003311 EXPECT_TRUE(
3312 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003313 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3314 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003315}
stefan658910c2015-09-03 05:48:32 -07003316
deadbeef884f5852016-01-15 09:20:04 -08003317TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003318 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003319 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3320 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003321
3322 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003323 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3324 EXPECT_TRUE(AddRecvStream(kSsrcX));
3325 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003326
3327 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003328 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3329 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003330
3331 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003332 channel_->SetRawAudioSink(kSsrcX, nullptr);
3333 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003334}
3335
solenberg2100c0b2017-03-01 11:29:29 -08003336TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003337 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003338 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3339 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003340 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3341 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003342
3343 // Should be able to set a default sink even when no stream exists.
3344 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3345
solenberg2100c0b2017-03-01 11:29:29 -08003346 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3347 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003348 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003349 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003350
3351 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003352 channel_->SetRawAudioSink(kSsrc0, nullptr);
3353 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003354
3355 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003356 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3357 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003358
3359 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003360 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003361 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003362 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3363
3364 // Spawn another unsignaled stream - it should be assigned the default sink
3365 // and the previous unsignaled stream should lose it.
3366 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3367 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3368 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3369 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003370 if (kMaxUnsignaledRecvStreams > 1) {
3371 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3372 }
solenberg2100c0b2017-03-01 11:29:29 -08003373 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3374
3375 // Reset the default sink - the second unsignaled stream should lose it.
3376 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003377 if (kMaxUnsignaledRecvStreams > 1) {
3378 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3379 }
solenberg2100c0b2017-03-01 11:29:29 -08003380 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3381
3382 // Try setting the default sink while two streams exists.
3383 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003384 if (kMaxUnsignaledRecvStreams > 1) {
3385 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3386 }
solenberg2100c0b2017-03-01 11:29:29 -08003387 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3388
3389 // Try setting the sink for the first unsignaled stream using its known SSRC.
3390 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003391 if (kMaxUnsignaledRecvStreams > 1) {
3392 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3393 }
solenberg2100c0b2017-03-01 11:29:29 -08003394 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003395 if (kMaxUnsignaledRecvStreams > 1) {
3396 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3397 }
deadbeef884f5852016-01-15 09:20:04 -08003398}
3399
skvlad7a43d252016-03-22 15:32:27 -07003400// Test that, just like the video channel, the voice channel communicates the
3401// network state to the call.
3402TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003403 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003404
3405 EXPECT_EQ(webrtc::kNetworkUp,
3406 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3407 EXPECT_EQ(webrtc::kNetworkUp,
3408 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3409
3410 channel_->OnReadyToSend(false);
3411 EXPECT_EQ(webrtc::kNetworkDown,
3412 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3413 EXPECT_EQ(webrtc::kNetworkUp,
3414 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3415
3416 channel_->OnReadyToSend(true);
3417 EXPECT_EQ(webrtc::kNetworkUp,
3418 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3419 EXPECT_EQ(webrtc::kNetworkUp,
3420 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3421}
3422
aleloi18e0b672016-10-04 02:45:47 -07003423// Test that playout is still started after changing parameters
3424TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3425 SetupRecvStream();
3426 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003427 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003428
3429 // Changing RTP header extensions will recreate the AudioReceiveStream.
3430 cricket::AudioRecvParameters parameters;
3431 parameters.extensions.push_back(
3432 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3433 channel_->SetRecvParameters(parameters);
3434
solenberg2100c0b2017-03-01 11:29:29 -08003435 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003436}
3437
Zhi Huangfa266ef2017-12-13 10:27:46 -08003438// Tests when GetSources is called with non-existing ssrc, it will return an
3439// empty list of RtpSource without crashing.
3440TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3441 // Setup an recv stream with |kSsrcX|.
3442 SetupRecvStream();
3443 cricket::WebRtcVoiceMediaChannel* media_channel =
3444 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3445 // Call GetSources with |kSsrcY| which doesn't exist.
3446 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3447 EXPECT_EQ(0u, sources.size());
3448}
3449
stefan658910c2015-09-03 05:48:32 -07003450// Tests that the library initializes and shuts down properly.
3451TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003452 // If the VoiceEngine wants to gather available codecs early, that's fine but
3453 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003454 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003455 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003456 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003457 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003458 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003459 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003460 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003461 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003462 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003463 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003464 cricket::VoiceMediaChannel* channel =
3465 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3466 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003467 EXPECT_TRUE(channel != nullptr);
3468 delete channel;
solenbergff976312016-03-30 23:28:51 -07003469}
stefan658910c2015-09-03 05:48:32 -07003470
solenbergff976312016-03-30 23:28:51 -07003471// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003472TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3473 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003474 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003475 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003476 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003477 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003478 {
peaha9cc40b2017-06-29 08:32:09 -07003479 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003480 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003481 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003482 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003483 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003484 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003485 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003486 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003487 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003488 cricket::VoiceMediaChannel* channel =
3489 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3490 cricket::AudioOptions(), webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003491 EXPECT_TRUE(channel != nullptr);
3492 delete channel;
3493 }
stefan658910c2015-09-03 05:48:32 -07003494}
3495
ossu20a4b3f2017-04-27 02:08:52 -07003496// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3497TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003498 // TODO(ossu): Why are the payload types of codecs with non-static payload
3499 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003500 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003501 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003502 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003503 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003504 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003505 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003506 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003507 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003508 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003509 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003510 (clockrate == 0 || codec.clockrate == clockrate);
3511 };
3512 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003513 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003514 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003515 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003516 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003517 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003518 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003519 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003520 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003521 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003522 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003523 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003524 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3525 // Remove these checks once both send and receive side assigns payload
3526 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003527 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003528 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003529 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003530 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003531 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003532 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003533 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003534 EXPECT_EQ(111, codec.id);
3535 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3536 EXPECT_EQ("10", codec.params.find("minptime")->second);
3537 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3538 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003539 }
3540 }
stefan658910c2015-09-03 05:48:32 -07003541}
3542
3543// Tests that VoE supports at least 32 channels
3544TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003545 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003546 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003547 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003548 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003549 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003550 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003551 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003552 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003553 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003554 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003555
3556 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003557 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003558 while (num_channels < arraysize(channels)) {
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003559 cricket::VoiceMediaChannel* channel =
3560 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3561 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003562 if (!channel)
3563 break;
stefan658910c2015-09-03 05:48:32 -07003564 channels[num_channels++] = channel;
3565 }
3566
Mirko Bonadeif859e552018-05-30 15:31:29 +02003567 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003568 EXPECT_EQ(expected, num_channels);
3569
3570 while (num_channels > 0) {
3571 delete channels[--num_channels];
3572 }
stefan658910c2015-09-03 05:48:32 -07003573}
3574
3575// Test that we set our preferred codecs properly.
3576TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003577 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3578 // - Check that our builtin codecs are usable by Channel.
3579 // - The codecs provided by the engine is usable by Channel.
3580 // It does not check that the codecs in the RecvParameters are actually
3581 // what we sent in - though it's probably reasonable to expect so, if
3582 // SetRecvParameters returns true.
3583 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003584 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003585 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003586 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003587 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003588 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003589 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003590 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003591 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003592 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003593 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003594 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003595 cricket::AudioOptions(),
3596 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003597 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003598 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003599 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003600}
ossu9def8002017-02-09 05:14:32 -08003601
3602TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3603 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003604 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3605 {48000, 2, 16000, 10000, 20000}};
3606 spec1.info.allow_comfort_noise = false;
3607 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003608 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003609 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3610 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003611 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003612 specs.push_back(webrtc::AudioCodecSpec{
3613 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3614 {16000, 1, 13300}});
3615 specs.push_back(
3616 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3617 specs.push_back(
3618 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003619
ossueb1fde42017-05-02 06:46:30 -07003620 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3621 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3622 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003623 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003624 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003625 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003626 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003627
peaha9cc40b2017-06-29 08:32:09 -07003628 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003629 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003630 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003631 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003632 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003633 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003634 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003635
3636 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3637 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003638 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3639 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3640 if (codecs.size() > index)
3641 return codecs[index];
3642 return missing_codec;
3643 };
ossu9def8002017-02-09 05:14:32 -08003644
3645 // Ensure the general codecs are generated first and in order.
3646 for (size_t i = 0; i != specs.size(); ++i) {
3647 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3648 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3649 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3650 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3651 }
3652
3653 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003654 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003655 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3656 for (size_t i = 0; i != codecs.size(); ++i) {
3657 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003658 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003659 codec.clockrate == format.clockrate_hz &&
3660 codec.channels == format.num_channels) {
3661 return rtc::checked_cast<int>(i);
3662 }
3663 }
3664 return -1;
3665 };
ossu9def8002017-02-09 05:14:32 -08003666
3667 // Ensure all supplementary codecs are generated last. Their internal ordering
3668 // is not important.
3669 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3670 const int num_specs = static_cast<int>(specs.size());
3671 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3672 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3673 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3674 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3675 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3676 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3677 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3678}