blob: 9fd5dfb0ad85c4f7839da8a334ca3e1329302077 [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::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100214 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
215 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.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100764TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
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 callee.
1639TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001640 EXPECT_TRUE(SetupRecvStream());
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, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001647 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001648 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001649
Yves Gerey665174f2018-06-19 15:03:05 +02001650 EXPECT_TRUE(
1651 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001652}
1653
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001654// Test that we can enable NACK on receive streams.
1655TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001656 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001657 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters parameters;
1659 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001660 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1661 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001662 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001663 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001664 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665}
1666
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667// Test that we can disable NACK on receive streams.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
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));
solenberg059fb442016-10-26 05:12:24 -07001675 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 parameters.codecs.clear();
1679 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001680 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001681 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001682}
1683
1684// Test that NACK is enabled on a new receive stream.
1685TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001686 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001687 cricket::AudioSendParameters parameters;
1688 parameters.codecs.push_back(kIsacCodec);
1689 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001690 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1691 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_TRUE(AddRecvStream(kSsrcY));
1695 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1696 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1697 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698}
1699
stefanba4c0e42016-02-04 04:12:24 -08001700TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001701 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001702 cricket::AudioSendParameters send_parameters;
1703 send_parameters.codecs.push_back(kOpusCodec);
1704 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001706
1707 cricket::AudioRecvParameters recv_parameters;
1708 recv_parameters.codecs.push_back(kIsacCodec);
1709 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001710 EXPECT_TRUE(AddRecvStream(kSsrcX));
1711 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001712 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001713 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001714
ossudedfd282016-06-14 07:12:39 -07001715 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001717 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001718 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001719 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001720}
1721
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001722// Test that we can switch back and forth between Opus and ISAC with CN.
1723TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001725
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001726 cricket::AudioSendParameters opus_parameters;
1727 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001729 {
ossu20a4b3f2017-04-27 02:08:52 -07001730 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1731 EXPECT_EQ(111, spec.payload_type);
1732 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters isac_parameters;
1736 isac_parameters.codecs.push_back(kIsacCodec);
1737 isac_parameters.codecs.push_back(kCn16000Codec);
1738 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001740 {
ossu20a4b3f2017-04-27 02:08:52 -07001741 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1742 EXPECT_EQ(103, spec.payload_type);
1743 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001744 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745
solenberg059fb442016-10-26 05:12:24 -07001746 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001747 {
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(111, spec.payload_type);
1750 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001751 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752}
1753
1754// Test that we handle various ways of specifying bitrate.
1755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001756 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters parameters;
1758 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001760 {
ossu20a4b3f2017-04-27 02:08:52 -07001761 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1762 EXPECT_EQ(103, spec.payload_type);
1763 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1764 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001765 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766
Yves Gerey665174f2018-06-19 15:03:05 +02001767 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001768 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001769 {
ossu20a4b3f2017-04-27 02:08:52 -07001770 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1771 EXPECT_EQ(103, spec.payload_type);
1772 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1773 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001774 }
Yves Gerey665174f2018-06-19 15:03:05 +02001775 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001776 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001777 {
ossu20a4b3f2017-04-27 02:08:52 -07001778 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1779 EXPECT_EQ(103, spec.payload_type);
1780 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1781 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001782 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001783
Yves Gerey665174f2018-06-19 15:03:05 +02001784 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001785 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001786 {
ossu20a4b3f2017-04-27 02:08:52 -07001787 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1788 EXPECT_EQ(0, spec.payload_type);
1789 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1790 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001791 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792
Yves Gerey665174f2018-06-19 15:03:05 +02001793 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001795 {
ossu20a4b3f2017-04-27 02:08:52 -07001796 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1797 EXPECT_EQ(0, spec.payload_type);
1798 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1799 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001800 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001803 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001804 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001805 {
ossu20a4b3f2017-04-27 02:08:52 -07001806 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1807 EXPECT_EQ(111, spec.payload_type);
1808 EXPECT_STREQ("opus", spec.format.name.c_str());
1809 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001810 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811}
1812
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001813// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001815 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 cricket::AudioSendParameters parameters;
1817 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001818}
1819
1820// Test that we can set send codecs even with telephone-event codec as the first
1821// one on the list.
1822TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001823 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001825 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs.push_back(kIsacCodec);
1827 parameters.codecs.push_back(kPcmuCodec);
1828 parameters.codecs[0].id = 98; // DTMF
1829 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001831 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1832 EXPECT_EQ(96, spec.payload_type);
1833 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001834 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001835 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001836}
1837
Harald Alvestranda1f66612018-02-21 11:24:23 +01001838// Test that CanInsertDtmf() is governed by the send flag
1839TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1840 EXPECT_TRUE(SetupSendStream());
1841 cricket::AudioSendParameters parameters;
1842 parameters.codecs.push_back(kTelephoneEventCodec1);
1843 parameters.codecs.push_back(kPcmuCodec);
1844 parameters.codecs[0].id = 98; // DTMF
1845 parameters.codecs[1].id = 96;
1846 SetSendParameters(parameters);
1847 EXPECT_FALSE(channel_->CanInsertDtmf());
1848 SetSend(true);
1849 EXPECT_TRUE(channel_->CanInsertDtmf());
1850 SetSend(false);
1851 EXPECT_FALSE(channel_->CanInsertDtmf());
1852}
1853
solenberg31642aa2016-03-14 08:00:37 -07001854// Test that payload type range is limited for telephone-event codec.
1855TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001856 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001857 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001858 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001859 parameters.codecs.push_back(kIsacCodec);
1860 parameters.codecs[0].id = 0; // DTMF
1861 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001863 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001864 EXPECT_TRUE(channel_->CanInsertDtmf());
1865 parameters.codecs[0].id = 128; // DTMF
1866 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1867 EXPECT_FALSE(channel_->CanInsertDtmf());
1868 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001869 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001870 EXPECT_TRUE(channel_->CanInsertDtmf());
1871 parameters.codecs[0].id = -1; // DTMF
1872 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1873 EXPECT_FALSE(channel_->CanInsertDtmf());
1874}
1875
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001876// Test that we can set send codecs even with CN codec as the first
1877// one on the list.
1878TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001879 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 cricket::AudioSendParameters parameters;
1881 parameters.codecs.push_back(kCn16000Codec);
1882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs.push_back(kPcmuCodec);
1884 parameters.codecs[0].id = 98; // wideband CN
1885 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001886 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001887 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1888 EXPECT_EQ(96, send_codec_spec.payload_type);
1889 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001890 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001891}
1892
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001893// Test that we set VAD and DTMF types correctly as caller.
1894TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001895 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001896 cricket::AudioSendParameters parameters;
1897 parameters.codecs.push_back(kIsacCodec);
1898 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 parameters.codecs.push_back(kCn16000Codec);
1901 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001902 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001903 parameters.codecs[0].id = 96;
1904 parameters.codecs[2].id = 97; // wideband CN
1905 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001906 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001907 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1908 EXPECT_EQ(96, send_codec_spec.payload_type);
1909 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001910 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001911 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001912 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001913 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001914}
1915
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001916// Test that we set VAD and DTMF types correctly as callee.
1917TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001918 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001919 cricket::AudioSendParameters parameters;
1920 parameters.codecs.push_back(kIsacCodec);
1921 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001922 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 parameters.codecs.push_back(kCn16000Codec);
1924 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001925 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001926 parameters.codecs[0].id = 96;
1927 parameters.codecs[2].id = 97; // wideband CN
1928 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001929 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001930 EXPECT_TRUE(
1931 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001932
ossu20a4b3f2017-04-27 02:08:52 -07001933 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1934 EXPECT_EQ(96, send_codec_spec.payload_type);
1935 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001936 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001937 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001938 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001939 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001940}
1941
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001942// Test that we only apply VAD if we have a CN codec that matches the
1943// send codec clockrate.
1944TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001945 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001946 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001947 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001948 parameters.codecs.push_back(kIsacCodec);
1949 parameters.codecs.push_back(kCn16000Codec);
1950 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001952 {
ossu20a4b3f2017-04-27 02:08:52 -07001953 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1954 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001955 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001956 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001957 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001961 {
ossu20a4b3f2017-04-27 02:08:52 -07001962 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1963 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001964 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001968 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001969 {
ossu20a4b3f2017-04-27 02:08:52 -07001970 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1971 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001972 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001973 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001974 }
Brave Yao5225dd82015-03-26 07:39:19 +08001975 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001978 {
ossu20a4b3f2017-04-27 02:08:52 -07001979 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1980 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001981 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001982 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001983}
1984
1985// Test that we perform case-insensitive matching of codec names.
1986TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001987 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001988 cricket::AudioSendParameters parameters;
1989 parameters.codecs.push_back(kIsacCodec);
1990 parameters.codecs.push_back(kPcmuCodec);
1991 parameters.codecs.push_back(kCn16000Codec);
1992 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001993 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001994 parameters.codecs[0].name = "iSaC";
1995 parameters.codecs[0].id = 96;
1996 parameters.codecs[2].id = 97; // wideband CN
1997 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001999 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2000 EXPECT_EQ(96, send_codec_spec.payload_type);
2001 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002002 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002003 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002004 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002005 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002006}
2007
stefanba4c0e42016-02-04 04:12:24 -08002008class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2009 public:
2010 WebRtcVoiceEngineWithSendSideBweTest()
2011 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2012};
2013
2014TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2015 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002016 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002017 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002018 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2019 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2020 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002021 extension.id);
2022 return;
2023 }
2024 }
2025 FAIL() << "Transport sequence number extension not in header-extension list.";
2026}
2027
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002028// Test support for audio level header extension.
2029TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002030 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002031}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002032TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002033 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002034}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002035
solenbergd4adce42016-11-17 06:26:52 -08002036// Test support for transport sequence number header extension.
2037TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2038 TestSetSendRtpHeaderExtensions(
2039 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002040}
solenbergd4adce42016-11-17 06:26:52 -08002041TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2042 TestSetRecvRtpHeaderExtensions(
2043 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002044}
2045
solenberg1ac56142015-10-13 03:58:19 -07002046// Test that we can create a channel and start sending on it.
2047TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002048 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002049 SetSendParameters(send_parameters_);
2050 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002051 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002052 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002053 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002054}
2055
2056// Test that a channel will send if and only if it has a source and is enabled
2057// for sending.
2058TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002059 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002060 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002061 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002062 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002063 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2064 SetAudioSend(kSsrcX, true, &fake_source_);
2065 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2066 SetAudioSend(kSsrcX, true, nullptr);
2067 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002068}
2069
solenberg94218532016-06-16 10:53:22 -07002070// Test that a channel is muted/unmuted.
2071TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2072 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002073 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002074 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2075 SetAudioSend(kSsrcX, true, nullptr);
2076 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2077 SetAudioSend(kSsrcX, false, nullptr);
2078 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002079}
2080
solenberg6d6e7c52016-04-13 09:07:30 -07002081// Test that SetSendParameters() does not alter a stream's send state.
2082TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2083 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002084 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002085
2086 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002087 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002088 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002089
2090 // Changing RTP header extensions will recreate the AudioSendStream.
2091 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002092 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002093 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002095
2096 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002097 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002098 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002099
2100 // Changing RTP header extensions will recreate the AudioSendStream.
2101 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002102 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002103 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002104}
2105
solenberg1ac56142015-10-13 03:58:19 -07002106// Test that we can create a channel and start playing out on it.
2107TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002108 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002109 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002110 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002112 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002113 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002114}
2115
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002116// Test that we can add and remove send streams.
2117TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2118 SetupForMultiSendStream();
2119
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002121 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122
solenbergc96df772015-10-21 13:01:53 -07002123 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002124 EXPECT_TRUE(
2125 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002126 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002128 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129 }
tfarina5237aaf2015-11-10 23:44:30 -08002130 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131
solenbergc96df772015-10-21 13:01:53 -07002132 // Delete the send streams.
2133 for (uint32_t ssrc : kSsrcs4) {
2134 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002135 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002136 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137 }
solenbergc96df772015-10-21 13:01:53 -07002138 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139}
2140
2141// Test SetSendCodecs correctly configure the codecs in all send streams.
2142TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2143 SetupForMultiSendStream();
2144
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002146 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002147 EXPECT_TRUE(
2148 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149 }
2150
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002151 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002153 parameters.codecs.push_back(kIsacCodec);
2154 parameters.codecs.push_back(kCn16000Codec);
2155 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002156 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157
2158 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002159 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002160 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2161 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002162 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2163 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002164 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002165 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002166 }
2167
minyue7a973442016-10-20 03:27:12 -07002168 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002170 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002171 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002172 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2173 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002174 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2175 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002176 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177 }
2178}
2179
2180// Test we can SetSend on all send streams correctly.
2181TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2182 SetupForMultiSendStream();
2183
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002184 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002185 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002186 EXPECT_TRUE(
2187 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002188 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002189 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
2191
2192 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002193 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002194 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002196 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197 }
2198
2199 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002200 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002201 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002202 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002203 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002204 }
2205}
2206
2207// Test we can set the correct statistics on all send streams.
2208TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2209 SetupForMultiSendStream();
2210
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002212 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002213 EXPECT_TRUE(
2214 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 }
solenberg85a04962015-10-27 03:35:21 -07002216
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002217 // Create a receive stream to check that none of the send streams end up in
2218 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002219 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002220
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002222 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002223 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002224 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002225
solenberg85a04962015-10-27 03:35:21 -07002226 // Check stats for the added streams.
2227 {
2228 cricket::VoiceMediaInfo info;
2229 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002230
solenberg85a04962015-10-27 03:35:21 -07002231 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002232 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002233 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002234 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002235 }
hbos1acfbd22016-11-17 23:43:29 -08002236 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002237
2238 // We have added one receive stream. We should see empty stats.
2239 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002240 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002241 }
solenberg1ac56142015-10-13 03:58:19 -07002242
solenberg2100c0b2017-03-01 11:29:29 -08002243 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002244 {
2245 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002246 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002247 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002248 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002249 EXPECT_EQ(0u, info.receivers.size());
2250 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002251
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002252 // Deliver a new packet - a default receive stream should be created and we
2253 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002254 {
2255 cricket::VoiceMediaInfo info;
2256 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2257 SetAudioReceiveStreamStats();
2258 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002259 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002260 EXPECT_EQ(1u, info.receivers.size());
2261 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002262 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002263 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002264}
2265
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002266// Test that we can add and remove receive streams, and do proper send/playout.
2267// We can receive on multiple streams while sending one stream.
2268TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002269 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002270
solenberg1ac56142015-10-13 03:58:19 -07002271 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002272 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002273 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274
solenberg1ac56142015-10-13 03:58:19 -07002275 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002276 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002277 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002278 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002279
solenberg1ac56142015-10-13 03:58:19 -07002280 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002281 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002282
2283 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002284 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2285 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2286 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
2288 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002289 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002290 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291
2292 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002293 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2295 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002296
aleloi84ef6152016-08-04 05:28:21 -07002297 // Restart playout and make sure recv streams are played out.
2298 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2300 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002301
aleloi84ef6152016-08-04 05:28:21 -07002302 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002303 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2304 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002305}
2306
wu@webrtc.org97077a32013-10-25 21:18:33 +00002307TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002308 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002309 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2310 .Times(1)
2311 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002312 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2313 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002314 send_parameters_.options.tx_agc_target_dbov = 3;
2315 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2316 send_parameters_.options.tx_agc_limiter = true;
2317 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002318 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2319 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2320 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002321 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002322}
2323
minyue6b825df2016-10-31 04:08:32 -07002324TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2325 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002326 send_parameters_.options.audio_network_adaptor = true;
2327 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002328 SetSendParameters(send_parameters_);
2329 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002330 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002331}
2332
2333TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2334 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002335 send_parameters_.options.audio_network_adaptor = true;
2336 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002337 SetSendParameters(send_parameters_);
2338 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002339 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002340 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002341 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002342 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002343 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002344}
2345
2346TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2347 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002348 send_parameters_.options.audio_network_adaptor = true;
2349 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002350 SetSendParameters(send_parameters_);
2351 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002352 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002353 const int initial_num = call_.GetNumCreatedSendStreams();
2354 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002355 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002356 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2357 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002358 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002359 // AudioSendStream not expected to be recreated.
2360 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2361 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002362 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002363}
2364
michaelt6672b262017-01-11 10:17:59 -08002365class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2366 : public WebRtcVoiceEngineTestFake {
2367 public:
2368 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2369 : WebRtcVoiceEngineTestFake(
2370 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2371 "Enabled/") {}
2372};
2373
2374TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2375 EXPECT_TRUE(SetupSendStream());
2376 cricket::AudioSendParameters parameters;
2377 parameters.codecs.push_back(kOpusCodec);
2378 SetSendParameters(parameters);
2379 const int initial_num = call_.GetNumCreatedSendStreams();
2380 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2381
2382 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2383 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002384 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2385 constexpr int kMinOverheadBps =
2386 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002387
2388 constexpr int kOpusMinBitrateBps = 6000;
2389 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002391 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002392 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002393 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002394
Oskar Sundbom78807582017-11-16 11:09:55 +01002395 parameters.options.audio_network_adaptor = true;
2396 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002397 SetSendParameters(parameters);
2398
ossu11bfc532017-02-16 05:37:06 -08002399 constexpr int kMinOverheadWithAnaBps =
2400 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002401
2402 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002403 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002404
minyuececec102017-03-27 13:04:25 -07002405 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002406 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002407}
2408
minyuececec102017-03-27 13:04:25 -07002409// This test is similar to
2410// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2411// additional field trial.
2412TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2413 SetRtpSendParameterUpdatesMaxBitrate) {
2414 EXPECT_TRUE(SetupSendStream());
2415 cricket::AudioSendParameters send_parameters;
2416 send_parameters.codecs.push_back(kOpusCodec);
2417 SetSendParameters(send_parameters);
2418
2419 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2420 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2421 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2422
2423 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002424 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002425 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002426
2427 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2428#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2429 constexpr int kMinOverhead = 3333;
2430#else
2431 constexpr int kMinOverhead = 6666;
2432#endif
2433 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2434}
2435
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002436// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002437// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002439 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002440 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441}
2442
2443TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2444 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002445 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002446 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002447 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002448 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002449 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002450 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002451 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452
solenberg85a04962015-10-27 03:35:21 -07002453 // Check stats for the added streams.
2454 {
2455 cricket::VoiceMediaInfo info;
2456 EXPECT_EQ(true, channel_->GetStats(&info));
2457
2458 // We have added one send stream. We should see the stats we've set.
2459 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002460 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002461 // We have added one receive stream. We should see empty stats.
2462 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002463 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002464 }
solenberg1ac56142015-10-13 03:58:19 -07002465
solenberg566ef242015-11-06 15:34:49 -08002466 // Start sending - this affects some reported stats.
2467 {
2468 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002469 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002470 EXPECT_EQ(true, channel_->GetStats(&info));
2471 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002472 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002473 }
2474
solenberg2100c0b2017-03-01 11:29:29 -08002475 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002476 {
2477 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002478 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002479 EXPECT_EQ(true, channel_->GetStats(&info));
2480 EXPECT_EQ(1u, info.senders.size());
2481 EXPECT_EQ(0u, info.receivers.size());
2482 }
solenberg1ac56142015-10-13 03:58:19 -07002483
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002484 // Deliver a new packet - a default receive stream should be created and we
2485 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002486 {
2487 cricket::VoiceMediaInfo info;
2488 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2489 SetAudioReceiveStreamStats();
2490 EXPECT_EQ(true, channel_->GetStats(&info));
2491 EXPECT_EQ(1u, info.senders.size());
2492 EXPECT_EQ(1u, info.receivers.size());
2493 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002494 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002495 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496}
2497
2498// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002499// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002501 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002502 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2503 EXPECT_TRUE(AddRecvStream(kSsrcY));
2504 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505}
2506
2507// Test that the local SSRC is the same on sending and receiving channels if the
2508// receive channel is created before the send channel.
2509TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002510 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002511 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002512 EXPECT_TRUE(
2513 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002514 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2515 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002516}
2517
2518// Test that we can properly receive packets.
2519TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002520 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002521 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002523
Yves Gerey665174f2018-06-19 15:03:05 +02002524 EXPECT_TRUE(
2525 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526}
2527
2528// Test that we can properly receive packets on multiple streams.
2529TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002530 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002531 const uint32_t ssrc1 = 1;
2532 const uint32_t ssrc2 = 2;
2533 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002534 EXPECT_TRUE(AddRecvStream(ssrc1));
2535 EXPECT_TRUE(AddRecvStream(ssrc2));
2536 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002537 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002538 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002539 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002541 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 }
mflodman3d7db262016-04-29 00:57:13 -07002543
2544 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2545 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2546 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2547
2548 EXPECT_EQ(s1.received_packets(), 0);
2549 EXPECT_EQ(s2.received_packets(), 0);
2550 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002551
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002552 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002553 EXPECT_EQ(s1.received_packets(), 0);
2554 EXPECT_EQ(s2.received_packets(), 0);
2555 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002556
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002558 EXPECT_EQ(s1.received_packets(), 1);
2559 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2560 EXPECT_EQ(s2.received_packets(), 0);
2561 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002562
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002563 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002564 EXPECT_EQ(s1.received_packets(), 1);
2565 EXPECT_EQ(s2.received_packets(), 1);
2566 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2567 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002568
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002569 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002570 EXPECT_EQ(s1.received_packets(), 1);
2571 EXPECT_EQ(s2.received_packets(), 1);
2572 EXPECT_EQ(s3.received_packets(), 1);
2573 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002574
mflodman3d7db262016-04-29 00:57:13 -07002575 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2576 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2577 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002578}
2579
solenberg2100c0b2017-03-01 11:29:29 -08002580// Test that receiving on an unsignaled stream works (a stream is created).
2581TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002582 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002583 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002584
solenberg7e63ef02015-11-20 00:19:43 -08002585 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002586
Mirko Bonadeif859e552018-05-30 15:31:29 +02002587 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002588 EXPECT_TRUE(
2589 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002590}
2591
Seth Hampson5897a6e2018-04-03 11:16:33 -07002592// Tests that when we add a stream without SSRCs, but contains a stream_id
2593// that it is stored and its stream id is later used when the first packet
2594// arrives to properly create a receive stream with a sync label.
2595TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2596 const char kSyncLabel[] = "sync_label";
2597 EXPECT_TRUE(SetupChannel());
2598 cricket::StreamParams unsignaled_stream;
2599 unsignaled_stream.set_stream_ids({kSyncLabel});
2600 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2601 // The stream shouldn't have been created at this point because it doesn't
2602 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002603 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002604
2605 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2606
Mirko Bonadeif859e552018-05-30 15:31:29 +02002607 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002608 EXPECT_TRUE(
2609 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2610 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2611
2612 // Removing the unsignaled stream clears the cached parameters. If a new
2613 // default unsignaled receive stream is created it will not have a sync group.
2614 channel_->RemoveRecvStream(0);
2615 channel_->RemoveRecvStream(kSsrc1);
2616
2617 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2618
Mirko Bonadeif859e552018-05-30 15:31:29 +02002619 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002620 EXPECT_TRUE(
2621 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2622 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2623}
2624
solenberg2100c0b2017-03-01 11:29:29 -08002625// Test that receiving N unsignaled stream works (streams will be created), and
2626// that packets are forwarded to them all.
2627TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002628 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002629 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002630 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2631
solenberg2100c0b2017-03-01 11:29:29 -08002632 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002633 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002634 rtc::SetBE32(&packet[8], ssrc);
2635 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002636
solenberg2100c0b2017-03-01 11:29:29 -08002637 // Verify we have one new stream for each loop iteration.
2638 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002639 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2640 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002641 }
mflodman3d7db262016-04-29 00:57:13 -07002642
solenberg2100c0b2017-03-01 11:29:29 -08002643 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002644 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002645 rtc::SetBE32(&packet[8], ssrc);
2646 DeliverPacket(packet, sizeof(packet));
2647
solenbergebb349d2017-03-13 05:46:15 -07002648 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002649 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2650 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2651 }
2652
2653 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2654 constexpr uint32_t kAnotherSsrc = 667;
2655 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002656 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002657
2658 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002659 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002660 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002661 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002662 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2663 EXPECT_EQ(2, streams[i]->received_packets());
2664 }
2665 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2666 EXPECT_EQ(1, streams[i]->received_packets());
2667 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002668 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002669}
2670
solenberg2100c0b2017-03-01 11:29:29 -08002671// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002672// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002673TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002675 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002676 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2677
2678 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002679 const uint32_t signaled_ssrc = 1;
2680 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002681 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002682 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002683 EXPECT_TRUE(
2684 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002685 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002686
2687 // Note that the first unknown SSRC cannot be 0, because we only support
2688 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002689 const uint32_t unsignaled_ssrc = 7011;
2690 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002691 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002692 EXPECT_TRUE(
2693 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002694 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002695
2696 DeliverPacket(packet, sizeof(packet));
2697 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2698
2699 rtc::SetBE32(&packet[8], signaled_ssrc);
2700 DeliverPacket(packet, sizeof(packet));
2701 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002702 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002703}
2704
solenberg4904fb62017-02-17 12:01:14 -08002705// Two tests to verify that adding a receive stream with the same SSRC as a
2706// previously added unsignaled stream will only recreate underlying stream
2707// objects if the stream parameters have changed.
2708TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2709 EXPECT_TRUE(SetupChannel());
2710
2711 // Spawn unsignaled stream with SSRC=1.
2712 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002713 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002714 EXPECT_TRUE(
2715 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002716
2717 // Verify that the underlying stream object in Call is not recreated when a
2718 // stream with SSRC=1 is added.
2719 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002720 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002721 int audio_receive_stream_id = streams.front()->id();
2722 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002723 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002724 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2725}
2726
2727TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2728 EXPECT_TRUE(SetupChannel());
2729
2730 // Spawn unsignaled stream with SSRC=1.
2731 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002732 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002733 EXPECT_TRUE(
2734 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002735
2736 // Verify that the underlying stream object in Call *is* recreated when a
2737 // stream with SSRC=1 is added, and which has changed stream parameters.
2738 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002739 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002740 int audio_receive_stream_id = streams.front()->id();
2741 cricket::StreamParams stream_params;
2742 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002743 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002744 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002745 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002746 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2747}
2748
solenberg1ac56142015-10-13 03:58:19 -07002749// Test that AddRecvStream creates new stream.
2750TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002751 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002752 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753}
2754
2755// Test that after adding a recv stream, we do not decode more codecs than
2756// those previously passed into SetRecvCodecs.
2757TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002758 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002759 cricket::AudioRecvParameters parameters;
2760 parameters.codecs.push_back(kIsacCodec);
2761 parameters.codecs.push_back(kPcmuCodec);
2762 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002763 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002764 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2765 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2766 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767}
2768
2769// Test that we properly clean up any streams that were added, even if
2770// not explicitly removed.
2771TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002774 EXPECT_TRUE(AddRecvStream(1));
2775 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002776
Mirko Bonadeif859e552018-05-30 15:31:29 +02002777 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2778 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002779 delete channel_;
2780 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002781 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2782 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783}
2784
wu@webrtc.org78187522013-10-07 23:32:02 +00002785TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002786 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002787 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002788}
2789
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002790TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002791 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002792 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002793 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002794}
2795
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002796// Test the InsertDtmf on default send stream as caller.
2797TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002798 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799}
2800
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002801// Test the InsertDtmf on default send stream as callee
2802TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002803 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002804}
2805
2806// Test the InsertDtmf on specified send stream as caller.
2807TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002808 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002809}
2810
2811// Test the InsertDtmf on specified send stream as callee.
2812TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002813 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002814}
2815
Johannes Kron9190b822018-10-29 11:22:05 +01002816// Test propagation of extmap allow mixed setting.
2817TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2818 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2819}
2820TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2821 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2822}
2823TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2824 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2825}
2826TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2827 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2828}
2829
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002831 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002832 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002833 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2834 .Times(9)
2835 .WillRepeatedly(Return(false));
2836 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2837 .Times(4)
2838 .WillRepeatedly(Return(false));
2839 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2840 .Times(2)
2841 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002842
Mirko Bonadeif859e552018-05-30 15:31:29 +02002843 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002844 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002845
solenberg246b8172015-12-08 09:50:23 -08002846 // Nothing set in AudioOptions, so everything should be as default.
2847 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002848 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002849 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002850 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002851 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002852 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002855 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002856 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002857 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858
2859 // Turn echo cancellation back on, with settings, and make sure
2860 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002861 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002862 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002863 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002865 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2866 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002867 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002868 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002869 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002870
2871 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 send_parameters_.options.delay_agnostic_aec = false;
2873 send_parameters_.options.extended_filter_aec = false;
2874 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002875 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002876 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002877
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002878 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002879 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002880 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002881 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002882
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002884 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002886 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002887 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002888 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
2890 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002891 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002892 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002894 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002895 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002897 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002898 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002900 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002903 send_parameters_.options.noise_suppression = false;
2904 send_parameters_.options.highpass_filter = false;
2905 send_parameters_.options.typing_detection = false;
2906 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002907 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002908 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002909 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg1ac56142015-10-13 03:58:19 -07002911 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002912 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002914 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002915 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2916 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002917 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002918 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002919}
2920
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002922 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002923 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2924 .Times(8)
2925 .WillRepeatedly(Return(false));
2926 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2927 .Times(8)
2928 .WillRepeatedly(Return(false));
2929 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2930 .Times(8)
2931 .WillRepeatedly(Return(false));
2932 EXPECT_CALL(adm_, RecordingIsInitialized())
2933 .Times(2)
2934 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002935 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2936 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002937 webrtc::AudioProcessing::Config apm_config;
2938 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002939 .WillRepeatedly(ReturnPointee(&apm_config));
2940 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002941 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002942 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002943
kwiberg686a8ef2016-02-26 03:00:35 -08002944 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002945 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2946 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2947 cricket::AudioOptions(),
2948 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002949 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002950 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2951 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2952 cricket::AudioOptions(),
2953 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002954
2955 // Have to add a stream to make SetSend work.
2956 cricket::StreamParams stream1;
2957 stream1.ssrcs.push_back(1);
2958 channel1->AddSendStream(stream1);
2959 cricket::StreamParams stream2;
2960 stream2.ssrcs.push_back(2);
2961 channel2->AddSendStream(stream2);
2962
2963 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002964 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002965 parameters_options_all.options.echo_cancellation = true;
2966 parameters_options_all.options.auto_gain_control = true;
2967 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002968 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002969 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002970 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002972 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002973 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002974 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002975 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002976 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002977 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978
2979 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002980 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002981 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002982 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002983 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002984 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002985 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002986 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002987 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002988 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002989 expected_options.echo_cancellation = true;
2990 expected_options.auto_gain_control = true;
2991 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002992 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
2994 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002995 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002996 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002997 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002998 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002999 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003000 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003001 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003002 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003003 expected_options.echo_cancellation = true;
3004 expected_options.auto_gain_control = false;
3005 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003006 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003008 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003009 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003010 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003011 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003012 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003013 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003015 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003016 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003017 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003018 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003019 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003020 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003022 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003023 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003024 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003025 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003026 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003027 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003030 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3031 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003032 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3033 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003034 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003035 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003036 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003037 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003038 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003039 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003040 expected_options.echo_cancellation = true;
3041 expected_options.auto_gain_control = false;
3042 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003043 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044}
3045
wu@webrtc.orgde305012013-10-31 15:40:38 +00003046// This test verifies DSCP settings are properly applied on voice media channel.
3047TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003048 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003049 cricket::FakeNetworkInterface network_interface;
3050 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003051 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003052 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003053
peahb1c9d1d2017-07-25 15:45:24 -07003054 webrtc::AudioProcessing::Config apm_config;
3055 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003056 .WillRepeatedly(ReturnPointee(&apm_config));
3057 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003058 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003059 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003060
Sebastian Jansson84848f22018-11-16 10:40:36 +01003061 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3062 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3063 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003064 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003065 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3066 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3067
3068 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003069 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3070 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3071 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003072 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003073 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3074
3075 // Create a send stream to configure
3076 EXPECT_TRUE(
3077 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3078 parameters = channel->GetRtpSendParameters(kSsrcZ);
3079 ASSERT_FALSE(parameters.encodings.empty());
3080
3081 // Various priorities map to various dscp values.
3082 parameters.encodings[0].network_priority = 4.0;
3083 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003084 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003085 parameters.encodings[0].network_priority = 0.5;
3086 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3087 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3088
3089 // A bad priority does not change the dscp value.
3090 parameters.encodings[0].network_priority = 0.0;
3091 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3092 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003093
Tim Haloun6ca98362018-09-17 17:06:08 -07003094 // Packets should also self-identify their dscp in PacketOptions.
3095 const uint8_t kData[10] = {0};
3096 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003097 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003098
nisse51542be2016-02-12 02:27:06 -08003099 // Verify that setting the option to false resets the
3100 // DiffServCodePoint.
3101 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003102 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3103 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3104 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003105 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003106 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3107 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3108
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003109 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003110}
3111
solenberg4bac9c52015-10-09 02:32:53 -07003112TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003113 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003114 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003115 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003116 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003117 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003118 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3119 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3120 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003121}
3122
solenberg2100c0b2017-03-01 11:29:29 -08003123TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003124 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003125
3126 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003127 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003128 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3129
3130 // Should remember the volume "2" which will be set on new unsignaled streams,
3131 // and also set the gain to 2 on existing unsignaled streams.
3132 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3133 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3134
3135 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3136 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3137 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3138 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3139 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3140 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3141
3142 // Setting gain with SSRC=0 should affect all unsignaled streams.
3143 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003144 if (kMaxUnsignaledRecvStreams > 1) {
3145 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3146 }
solenberg2100c0b2017-03-01 11:29:29 -08003147 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3148
3149 // Setting gain on an individual stream affects only that.
3150 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003151 if (kMaxUnsignaledRecvStreams > 1) {
3152 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3153 }
solenberg2100c0b2017-03-01 11:29:29 -08003154 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003155}
3156
Seth Hampson845e8782018-03-02 11:34:10 -08003157TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003158 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003159 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003160
solenbergff976312016-03-30 23:28:51 -07003161 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003162 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003163 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003164 // Creating two channels to make sure that sync label is set properly for both
3165 // the default voice channel and following ones.
3166 EXPECT_TRUE(channel_->AddRecvStream(sp));
3167 sp.ssrcs[0] += 1;
3168 EXPECT_TRUE(channel_->AddRecvStream(sp));
3169
Mirko Bonadeif859e552018-05-30 15:31:29 +02003170 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003171 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003172 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003173 << "SyncGroup should be set based on stream id";
3174 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003175 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003176 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003177}
3178
solenberg3a941542015-11-16 07:34:50 -08003179// TODO(solenberg): Remove, once recv streams are configured through Call.
3180// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003181TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003182 // Test that setting the header extensions results in the expected state
3183 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003184 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003185 ssrcs.push_back(223);
3186 ssrcs.push_back(224);
3187
solenbergff976312016-03-30 23:28:51 -07003188 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003189 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003190 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003191 EXPECT_TRUE(
3192 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003193 }
3194
Mirko Bonadeif859e552018-05-30 15:31:29 +02003195 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003196 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003197 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003198 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003199 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 }
3201
3202 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003203 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003204 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003205 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003206 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003207 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003208 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003209 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003210 EXPECT_NE(nullptr, s);
3211 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003212 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3213 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214 for (const auto& s_ext : s_exts) {
3215 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003216 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003217 }
3218 }
3219 }
3220 }
3221
3222 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003223 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003224 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003225 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003226 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003227 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003228 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229}
3230
3231TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3232 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003233 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003234 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003235 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003236 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3237 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003239 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003240
solenbergff976312016-03-30 23:28:51 -07003241 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003242 cricket::WebRtcVoiceMediaChannel* media_channel =
3243 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003244 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003245 EXPECT_TRUE(media_channel->AddRecvStream(
3246 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3247
Mirko Bonadeif859e552018-05-30 15:31:29 +02003248 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003249 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003250 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003251 EXPECT_EQ(0, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003252 channel_->OnPacketReceived(&kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003253 EXPECT_EQ(1, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003254 channel_->OnRtcpReceived(&kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003256}
Minyue2013aec2015-05-13 14:14:42 +02003257
solenberg0a617e22015-10-20 15:49:38 -07003258// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003259// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003260TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003261 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003262 EXPECT_TRUE(AddRecvStream(kSsrcY));
3263 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003264 EXPECT_TRUE(
3265 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3267 EXPECT_TRUE(AddRecvStream(kSsrcW));
3268 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003269}
3270
solenberg7602aab2016-11-14 11:30:07 -08003271TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3272 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003274 EXPECT_TRUE(
3275 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003276 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3277 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3278 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003279 EXPECT_TRUE(
3280 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3282 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003283}
stefan658910c2015-09-03 05:48:32 -07003284
deadbeef884f5852016-01-15 09:20:04 -08003285TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003286 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003287 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3288 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003289
3290 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003291 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3292 EXPECT_TRUE(AddRecvStream(kSsrcX));
3293 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003294
3295 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003296 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3297 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003298
3299 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003300 channel_->SetRawAudioSink(kSsrcX, nullptr);
3301 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003302}
3303
solenberg2100c0b2017-03-01 11:29:29 -08003304TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003305 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003306 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3307 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003308 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3309 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003310
3311 // Should be able to set a default sink even when no stream exists.
3312 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3313
solenberg2100c0b2017-03-01 11:29:29 -08003314 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3315 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003316 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003317 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003318
3319 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003320 channel_->SetRawAudioSink(kSsrc0, nullptr);
3321 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003322
3323 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003324 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3325 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003326
3327 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003328 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003329 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003330 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3331
3332 // Spawn another unsignaled stream - it should be assigned the default sink
3333 // and the previous unsignaled stream should lose it.
3334 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3335 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3336 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3337 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003338 if (kMaxUnsignaledRecvStreams > 1) {
3339 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3340 }
solenberg2100c0b2017-03-01 11:29:29 -08003341 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3342
3343 // Reset the default sink - the second unsignaled stream should lose it.
3344 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003345 if (kMaxUnsignaledRecvStreams > 1) {
3346 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3347 }
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3349
3350 // Try setting the default sink while two streams exists.
3351 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003352 if (kMaxUnsignaledRecvStreams > 1) {
3353 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3354 }
solenberg2100c0b2017-03-01 11:29:29 -08003355 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3356
3357 // Try setting the sink for the first unsignaled stream using its known SSRC.
3358 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003359 if (kMaxUnsignaledRecvStreams > 1) {
3360 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3361 }
solenberg2100c0b2017-03-01 11:29:29 -08003362 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003363 if (kMaxUnsignaledRecvStreams > 1) {
3364 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3365 }
deadbeef884f5852016-01-15 09:20:04 -08003366}
3367
skvlad7a43d252016-03-22 15:32:27 -07003368// Test that, just like the video channel, the voice channel communicates the
3369// network state to the call.
3370TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003371 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003372
3373 EXPECT_EQ(webrtc::kNetworkUp,
3374 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3375 EXPECT_EQ(webrtc::kNetworkUp,
3376 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3377
3378 channel_->OnReadyToSend(false);
3379 EXPECT_EQ(webrtc::kNetworkDown,
3380 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3381 EXPECT_EQ(webrtc::kNetworkUp,
3382 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3383
3384 channel_->OnReadyToSend(true);
3385 EXPECT_EQ(webrtc::kNetworkUp,
3386 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3387 EXPECT_EQ(webrtc::kNetworkUp,
3388 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3389}
3390
aleloi18e0b672016-10-04 02:45:47 -07003391// Test that playout is still started after changing parameters
3392TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3393 SetupRecvStream();
3394 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003395 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003396
3397 // Changing RTP header extensions will recreate the AudioReceiveStream.
3398 cricket::AudioRecvParameters parameters;
3399 parameters.extensions.push_back(
3400 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3401 channel_->SetRecvParameters(parameters);
3402
solenberg2100c0b2017-03-01 11:29:29 -08003403 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003404}
3405
Zhi Huangfa266ef2017-12-13 10:27:46 -08003406// Tests when GetSources is called with non-existing ssrc, it will return an
3407// empty list of RtpSource without crashing.
3408TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3409 // Setup an recv stream with |kSsrcX|.
3410 SetupRecvStream();
3411 cricket::WebRtcVoiceMediaChannel* media_channel =
3412 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3413 // Call GetSources with |kSsrcY| which doesn't exist.
3414 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3415 EXPECT_EQ(0u, sources.size());
3416}
3417
stefan658910c2015-09-03 05:48:32 -07003418// Tests that the library initializes and shuts down properly.
3419TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003420 // If the VoiceEngine wants to gather available codecs early, that's fine but
3421 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003422 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003423 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003424 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003425 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003426 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003427 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003428 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003429 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003430 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003431 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003432 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3433 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3434 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003435 EXPECT_TRUE(channel != nullptr);
3436 delete channel;
solenbergff976312016-03-30 23:28:51 -07003437}
stefan658910c2015-09-03 05:48:32 -07003438
solenbergff976312016-03-30 23:28:51 -07003439// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003440TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3441 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003442 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003443 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003444 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003445 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003446 {
peaha9cc40b2017-06-29 08:32:09 -07003447 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003448 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003449 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003450 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003451 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003452 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003453 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003454 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003455 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003456 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3457 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3458 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003459 EXPECT_TRUE(channel != nullptr);
3460 delete channel;
3461 }
stefan658910c2015-09-03 05:48:32 -07003462}
3463
ossu20a4b3f2017-04-27 02:08:52 -07003464// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3465TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003466 // TODO(ossu): Why are the payload types of codecs with non-static payload
3467 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003468 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003469 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003470 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003471 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003472 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003473 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003474 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003475 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003476 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003477 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003478 (clockrate == 0 || codec.clockrate == clockrate);
3479 };
3480 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003481 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003482 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003483 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003484 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003485 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003486 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003487 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003488 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003489 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003490 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003491 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003492 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3493 // Remove these checks once both send and receive side assigns payload
3494 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003495 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003496 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003497 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003498 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003499 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003500 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003501 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003502 EXPECT_EQ(111, codec.id);
3503 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3504 EXPECT_EQ("10", codec.params.find("minptime")->second);
3505 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3506 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003507 }
3508 }
stefan658910c2015-09-03 05:48:32 -07003509}
3510
3511// Tests that VoE supports at least 32 channels
3512TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003513 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003514 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003515 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003516 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003517 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003518 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003519 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003520 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003521 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003522 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003523
3524 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003525 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003526 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003527 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3528 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3529 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003530 if (!channel)
3531 break;
stefan658910c2015-09-03 05:48:32 -07003532 channels[num_channels++] = channel;
3533 }
3534
Mirko Bonadeif859e552018-05-30 15:31:29 +02003535 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003536 EXPECT_EQ(expected, num_channels);
3537
3538 while (num_channels > 0) {
3539 delete channels[--num_channels];
3540 }
stefan658910c2015-09-03 05:48:32 -07003541}
3542
3543// Test that we set our preferred codecs properly.
3544TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003545 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3546 // - Check that our builtin codecs are usable by Channel.
3547 // - The codecs provided by the engine is usable by Channel.
3548 // It does not check that the codecs in the RecvParameters are actually
3549 // what we sent in - though it's probably reasonable to expect so, if
3550 // SetRecvParameters returns true.
3551 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003552 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003553 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003554 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003555 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003556 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003557 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003558 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003559 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003560 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003561 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003562 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003563 cricket::AudioOptions(),
3564 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003565 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003566 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003567 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003568}
ossu9def8002017-02-09 05:14:32 -08003569
3570TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3571 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003572 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3573 {48000, 2, 16000, 10000, 20000}};
3574 spec1.info.allow_comfort_noise = false;
3575 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003576 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003577 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3578 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003579 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003580 specs.push_back(webrtc::AudioCodecSpec{
3581 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3582 {16000, 1, 13300}});
3583 specs.push_back(
3584 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3585 specs.push_back(
3586 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003587
ossueb1fde42017-05-02 06:46:30 -07003588 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3589 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3590 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003591 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003592 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003593 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003594 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003595
peaha9cc40b2017-06-29 08:32:09 -07003596 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003597 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003598 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003599 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003600 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003601 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003602 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003603
3604 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3605 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003606 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3607 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3608 if (codecs.size() > index)
3609 return codecs[index];
3610 return missing_codec;
3611 };
ossu9def8002017-02-09 05:14:32 -08003612
3613 // Ensure the general codecs are generated first and in order.
3614 for (size_t i = 0; i != specs.size(); ++i) {
3615 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3616 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3617 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3618 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3619 }
3620
3621 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003622 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003623 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3624 for (size_t i = 0; i != codecs.size(); ++i) {
3625 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003626 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003627 codec.clockrate == format.clockrate_hz &&
3628 codec.channels == format.num_channels) {
3629 return rtc::checked_cast<int>(i);
3630 }
3631 }
3632 return -1;
3633 };
ossu9def8002017-02-09 05:14:32 -08003634
3635 // Ensure all supplementary codecs are generated last. Their internal ordering
3636 // is not important.
3637 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3638 const int num_specs = static_cast<int>(specs.size());
3639 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3640 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3641 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3642 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3643 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3644 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3645 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3646}