blob: eefa6f0822de881df7cd7cef20588bf9cb952cab [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080017#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "call/call.h"
19#include "logging/rtc_event_log/rtc_event_log.h"
20#include "media/base/fakemediaengine.h"
21#include "media/base/fakenetworkinterface.h"
22#include "media/base/fakertp.h"
23#include "media/base/mediaconstants.h"
24#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/webrtcvoiceengine.h"
26#include "modules/audio_device/include/mock_audio_device.h"
27#include "modules/audio_processing/include/mock_audio_processing.h"
28#include "pc/channel.h"
29#include "rtc_base/arraysize.h"
30#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010031#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/scoped_ref_ptr.h"
33#include "test/field_trial.h"
34#include "test/gtest.h"
35#include "test/mock_audio_decoder_factory.h"
36#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010040using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070041using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070042using testing::ReturnPointee;
43using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070044using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000045
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020046namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010047using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048
solenberg418b7d32017-06-13 00:38:27 -070049constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070050
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
52const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070053const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
55const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
57const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020058const cricket::AudioCodec kTelephoneEventCodec1(106,
59 "telephone-event",
60 8000,
61 0,
62 1);
63const cricket::AudioCodec kTelephoneEventCodec2(107,
64 "telephone-event",
65 32000,
66 0,
67 1);
solenberg2779bab2016-11-17 04:45:19 -080068
solenberg2100c0b2017-03-01 11:29:29 -080069const uint32_t kSsrc0 = 0;
70const uint32_t kSsrc1 = 1;
71const uint32_t kSsrcX = 0x99;
72const uint32_t kSsrcY = 0x17;
73const uint32_t kSsrcZ = 0x42;
74const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020075const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076
solenberg971cab02016-06-14 10:02:41 -070077constexpr int kRtpHistoryMs = 5000;
78
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010079constexpr webrtc::GainControl::Mode kDefaultAgcMode =
80#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
81 webrtc::GainControl::kFixedDigital;
82#else
83 webrtc::GainControl::kAdaptiveAnalog;
84#endif
85
86constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
87 webrtc::NoiseSuppression::kHigh;
88
solenberg9a5f032222017-03-15 06:14:12 -070089void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
90 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010091
92 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010093 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010094 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010095 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070096#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020097 EXPECT_CALL(
98 *adm, SetPlayoutDevice(
99 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
100 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
101 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700102#else
103 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
104#endif // #if defined(WEBRTC_WIN)
105 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
106 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
107 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100108#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200109 EXPECT_CALL(
110 *adm, SetRecordingDevice(
111 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
112 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
113 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114#else
115 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
116#endif // #if defined(WEBRTC_WIN)
117 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
118 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
119 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700120 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
122 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100123
124 // Teardown.
125 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
127 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
128 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200129 EXPECT_CALL(*adm, Release())
130 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100131 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700132}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200133} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134
solenbergff976312016-03-30 23:28:51 -0700135// Tests that our stub library "works".
136TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700137 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700138 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700139 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
140 new rtc::RefCountedObject<
141 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700142 webrtc::AudioProcessing::Config apm_config;
143 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
144 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700146 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700147 {
ossuc54071d2016-08-17 02:45:41 -0700148 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700149 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100150 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700151 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700152 }
solenbergff976312016-03-30 23:28:51 -0700153}
154
deadbeef884f5852016-01-15 09:20:04 -0800155class FakeAudioSink : public webrtc::AudioSinkInterface {
156 public:
157 void OnData(const Data& audio) override {}
158};
159
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800160class FakeAudioSource : public cricket::AudioSource {
161 void SetSink(Sink* sink) override {}
162};
163
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164class WebRtcVoiceEngineTestFake : public testing::Test {
165 public:
stefanba4c0e42016-02-04 04:12:24 -0800166 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
167
168 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700169 : apm_(new rtc::RefCountedObject<
170 StrictMock<webrtc::test::MockAudioProcessing>>()),
171 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700172 apm_ns_(*apm_->noise_suppression()),
173 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100174 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700175 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800176 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700177 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800178 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700179 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
180 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700182 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800183 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100184 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800185 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100186 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
187 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800188 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800190 // Init does not overwrite default AGC config.
191 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
192 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
193 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800194 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
195 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700196 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800197 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700198 // factories. Those tests should probably be moved elsewhere.
199 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
200 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100201 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100202 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700203 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200204 send_parameters_.codecs.push_back(kPcmuCodec);
205 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100206
solenberg76377c52017-02-21 00:54:31 -0800207 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200208 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800209 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700213 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700214 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700215 cricket::AudioOptions(),
216 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200217 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000218 }
solenberg8189b022016-06-14 12:13:00 -0700219
solenbergff976312016-03-30 23:28:51 -0700220 bool SetupRecvStream() {
221 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700222 return false;
223 }
solenberg2100c0b2017-03-01 11:29:29 -0800224 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700225 }
solenberg8189b022016-06-14 12:13:00 -0700226
solenbergff976312016-03-30 23:28:51 -0700227 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200228 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
229 }
230
231 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700232 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000233 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
Florent Castellidacec712018-05-24 16:24:21 +0200235 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800236 return false;
237 }
peaha9cc40b2017-06-29 08:32:09 -0700238 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800239 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
242 bool AddRecvStream(uint32_t ssrc) {
243 EXPECT_TRUE(channel_);
244 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
245 }
246
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700248 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700249 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800250 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
251 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700252 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800253 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700257 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000258 channel_->OnPacketReceived(&packet, rtc::PacketTime());
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
354 // Test that send bandwidth is set correctly.
355 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000356 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
357 // |expected_result| is the expected result from SetMaxSendBandwidth().
358 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700359 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
360 int max_bitrate,
361 bool expected_result,
362 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200363 cricket::AudioSendParameters parameters;
364 parameters.codecs.push_back(codec);
365 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700366 if (expected_result) {
367 SetSendParameters(parameters);
368 } else {
369 EXPECT_FALSE(channel_->SetSendParameters(parameters));
370 }
solenberg2100c0b2017-03-01 11:29:29 -0800371 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000372 }
373
skvlade0d46372016-04-07 22:59:22 -0700374 // Sets the per-stream maximum bitrate limit for the specified SSRC.
375 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700376 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700377 EXPECT_EQ(1UL, parameters.encodings.size());
378
Oskar Sundbom78807582017-11-16 11:09:55 +0100379 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800380 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700381 }
382
solenberg059fb442016-10-26 05:12:24 -0700383 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700384 cricket::AudioSendParameters send_parameters;
385 send_parameters.codecs.push_back(codec);
386 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700387 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700388 }
389
ossu20a4b3f2017-04-27 02:08:52 -0700390 void CheckSendCodecBitrate(int32_t ssrc,
391 const char expected_name[],
392 int expected_bitrate) {
393 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
394 EXPECT_EQ(expected_name, spec->format.name);
395 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700396 }
397
Danil Chapovalov00c71832018-06-15 15:58:38 +0200398 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700399 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700400 }
401
Danil Chapovalov00c71832018-06-15 15:58:38 +0200402 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
403 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700404 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
405 }
406
skvlade0d46372016-04-07 22:59:22 -0700407 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
408 int global_max,
409 int stream_max,
410 bool expected_result,
411 int expected_codec_bitrate) {
412 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800413 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700414
415 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700416 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800417 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700418
419 // Verify that reading back the parameters gives results
420 // consistent with the Set() result.
421 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800422 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700423 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
424 EXPECT_EQ(expected_result ? stream_max : -1,
425 resulting_parameters.encodings[0].max_bitrate_bps);
426
427 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800428 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700429 }
430
stefan13f1a0a2016-11-30 07:22:58 -0800431 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
432 int expected_min_bitrate_bps,
433 const char* start_bitrate_kbps,
434 int expected_start_bitrate_bps,
435 const char* max_bitrate_kbps,
436 int expected_max_bitrate_bps) {
437 EXPECT_TRUE(SetupSendStream());
438 auto& codecs = send_parameters_.codecs;
439 codecs.clear();
440 codecs.push_back(kOpusCodec);
441 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
442 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
443 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100444 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
445 SetSdpBitrateParameters(
446 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
447 expected_min_bitrate_bps),
448 Field(&BitrateConstraints::start_bitrate_bps,
449 expected_start_bitrate_bps),
450 Field(&BitrateConstraints::max_bitrate_bps,
451 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800452
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100453 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800454 }
455
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000456 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700457 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800460 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000461
462 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700463 send_parameters_.extensions.push_back(
464 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700465 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800466 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000467
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000468 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200469 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700470 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800471 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000472
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 // Ensure extension is set properly.
474 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700475 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700476 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000480
solenberg7add0582015-11-20 09:59:34 -0800481 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200482 EXPECT_TRUE(
483 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
485 call_.GetAudioSendStream(kSsrcY));
486 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
487 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
488 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489
490 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200491 send_parameters_.codecs.push_back(kPcmuCodec);
492 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
495 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496 }
497
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000498 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700499 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000501 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800502 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000503
504 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700505 recv_parameters_.extensions.push_back(
506 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800507 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800508 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000509
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000510 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800511 recv_parameters_.extensions.clear();
512 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800513 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000514
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000515 // Ensure extension is set properly.
516 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700517 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800518 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800519 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
520 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
521 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000522
solenberg7add0582015-11-20 09:59:34 -0800523 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_TRUE(AddRecvStream(kSsrcY));
525 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
526 call_.GetAudioReceiveStream(kSsrcY));
527 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
528 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
529 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000530
531 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800532 recv_parameters_.extensions.clear();
533 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800534 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
535 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000536 }
537
solenberg85a04962015-10-27 03:35:21 -0700538 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
539 webrtc::AudioSendStream::Stats stats;
540 stats.local_ssrc = 12;
541 stats.bytes_sent = 345;
542 stats.packets_sent = 678;
543 stats.packets_lost = 9012;
544 stats.fraction_lost = 34.56f;
545 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100546 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700547 stats.ext_seqnum = 789;
548 stats.jitter_ms = 12;
549 stats.rtt_ms = 345;
550 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100551 stats.apm_statistics.delay_median_ms = 234;
552 stats.apm_statistics.delay_standard_deviation_ms = 567;
553 stats.apm_statistics.echo_return_loss = 890;
554 stats.apm_statistics.echo_return_loss_enhancement = 1234;
555 stats.apm_statistics.residual_echo_likelihood = 0.432f;
556 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100557 stats.ana_statistics.bitrate_action_counter = 321;
558 stats.ana_statistics.channel_action_counter = 432;
559 stats.ana_statistics.dtx_action_counter = 543;
560 stats.ana_statistics.fec_action_counter = 654;
561 stats.ana_statistics.frame_length_increase_counter = 765;
562 stats.ana_statistics.frame_length_decrease_counter = 876;
563 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700564 stats.typing_noise_detected = true;
565 return stats;
566 }
567 void SetAudioSendStreamStats() {
568 for (auto* s : call_.GetAudioSendStreams()) {
569 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200570 }
solenberg85a04962015-10-27 03:35:21 -0700571 }
solenberg566ef242015-11-06 15:34:49 -0800572 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
573 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700574 const auto stats = GetAudioSendStreamStats();
575 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
576 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
577 EXPECT_EQ(info.packets_sent, stats.packets_sent);
578 EXPECT_EQ(info.packets_lost, stats.packets_lost);
579 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
580 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800581 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700582 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
583 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
584 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
585 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100586 EXPECT_EQ(info.apm_statistics.delay_median_ms,
587 stats.apm_statistics.delay_median_ms);
588 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
589 stats.apm_statistics.delay_standard_deviation_ms);
590 EXPECT_EQ(info.apm_statistics.echo_return_loss,
591 stats.apm_statistics.echo_return_loss);
592 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
593 stats.apm_statistics.echo_return_loss_enhancement);
594 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
595 stats.apm_statistics.residual_echo_likelihood);
596 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
597 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700598 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
599 stats.ana_statistics.bitrate_action_counter);
600 EXPECT_EQ(info.ana_statistics.channel_action_counter,
601 stats.ana_statistics.channel_action_counter);
602 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
603 stats.ana_statistics.dtx_action_counter);
604 EXPECT_EQ(info.ana_statistics.fec_action_counter,
605 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700606 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
607 stats.ana_statistics.frame_length_increase_counter);
608 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
609 stats.ana_statistics.frame_length_decrease_counter);
610 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
611 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800612 EXPECT_EQ(info.typing_noise_detected,
613 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700614 }
615
616 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
617 webrtc::AudioReceiveStream::Stats stats;
618 stats.remote_ssrc = 123;
619 stats.bytes_rcvd = 456;
620 stats.packets_rcvd = 768;
621 stats.packets_lost = 101;
622 stats.fraction_lost = 23.45f;
623 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100624 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700625 stats.ext_seqnum = 678;
626 stats.jitter_ms = 901;
627 stats.jitter_buffer_ms = 234;
628 stats.jitter_buffer_preferred_ms = 567;
629 stats.delay_estimate_ms = 890;
630 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700631 stats.total_samples_received = 5678901;
632 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200633 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200634 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700635 stats.expand_rate = 5.67f;
636 stats.speech_expand_rate = 8.90f;
637 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200638 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700639 stats.accelerate_rate = 4.56f;
640 stats.preemptive_expand_rate = 7.89f;
641 stats.decoding_calls_to_silence_generator = 12;
642 stats.decoding_calls_to_neteq = 345;
643 stats.decoding_normal = 67890;
644 stats.decoding_plc = 1234;
645 stats.decoding_cng = 5678;
646 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700647 stats.decoding_muted_output = 3456;
648 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200649 return stats;
650 }
651 void SetAudioReceiveStreamStats() {
652 for (auto* s : call_.GetAudioReceiveStreams()) {
653 s->SetStats(GetAudioReceiveStreamStats());
654 }
655 }
656 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700657 const auto stats = GetAudioReceiveStreamStats();
658 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
659 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200660 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
661 stats.packets_rcvd);
662 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
663 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700664 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
665 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800666 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200667 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
668 stats.ext_seqnum);
669 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
670 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
671 stats.jitter_buffer_ms);
672 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700673 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200674 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
675 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700676 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700677 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
678 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200679 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200680 EXPECT_EQ(info.jitter_buffer_delay_seconds,
681 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700682 EXPECT_EQ(info.expand_rate, stats.expand_rate);
683 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
684 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200685 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700686 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
687 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200688 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700689 stats.decoding_calls_to_silence_generator);
690 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
691 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
692 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
693 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
694 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700695 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700696 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200697 }
hbos1acfbd22016-11-17 23:43:29 -0800698 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
699 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
700 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
701 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
702 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
703 codec.ToCodecParameters());
704 }
705 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
706 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
707 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
708 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
709 codec.ToCodecParameters());
710 }
711 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200712
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200713 bool IsEchoCancellationEnabled() {
714 return engine_->GetApmConfigForTest().echo_canceller.enabled;
715 }
716
peah8271d042016-11-22 07:24:52 -0800717 bool IsHighPassFilterEnabled() {
718 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
719 }
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700722 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700723 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800724 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800725 webrtc::test::MockNoiseSuppression& apm_ns_;
726 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200727 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700728 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700729 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200730 cricket::AudioSendParameters send_parameters_;
731 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800732 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700733 webrtc::AudioProcessing::Config apm_config_;
734
stefanba4c0e42016-02-04 04:12:24 -0800735 private:
736 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737};
738
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000739// Tests that we can create and destroy a channel.
740TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700741 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742}
743
solenberg31fec402016-05-06 02:13:12 -0700744// Test that we can add a send stream and that it has the correct defaults.
745TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
746 EXPECT_TRUE(SetupChannel());
747 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800748 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
749 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
750 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700751 EXPECT_EQ("", config.rtp.c_name);
752 EXPECT_EQ(0u, config.rtp.extensions.size());
753 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
754 config.send_transport);
755}
756
757// Test that we can add a receive stream and that it has the correct defaults.
758TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
759 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800760 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700761 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800762 GetRecvStreamConfig(kSsrcX);
763 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700764 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
765 EXPECT_FALSE(config.rtp.transport_cc);
766 EXPECT_EQ(0u, config.rtp.extensions.size());
767 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
768 config.rtcp_send_transport);
769 EXPECT_EQ("", config.sync_group);
770}
771
stefanba4c0e42016-02-04 04:12:24 -0800772TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700773 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800774 bool opus_found = false;
775 for (cricket::AudioCodec codec : codecs) {
776 if (codec.name == "opus") {
777 EXPECT_TRUE(HasTransportCc(codec));
778 opus_found = true;
779 }
780 }
781 EXPECT_TRUE(opus_found);
782}
783
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784// Test that we set our inbound codecs properly, including changing PT.
785TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700786 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200787 cricket::AudioRecvParameters parameters;
788 parameters.codecs.push_back(kIsacCodec);
789 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800790 parameters.codecs.push_back(kTelephoneEventCodec1);
791 parameters.codecs.push_back(kTelephoneEventCodec2);
792 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200793 parameters.codecs[2].id = 126;
794 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800795 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700796 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
797 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
798 {{0, {"PCMU", 8000, 1}},
799 {106, {"ISAC", 16000, 1}},
800 {126, {"telephone-event", 8000, 1}},
801 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802}
803
804// Test that we fail to set an unknown inbound codec.
805TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700806 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200807 cricket::AudioRecvParameters parameters;
808 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700809 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811}
812
813// Test that we fail if we have duplicate types in the inbound list.
814TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700815 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200816 cricket::AudioRecvParameters parameters;
817 parameters.codecs.push_back(kIsacCodec);
818 parameters.codecs.push_back(kCn16000Codec);
819 parameters.codecs[1].id = kIsacCodec.id;
820 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821}
822
823// Test that we can decode OPUS without stereo parameters.
824TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700825 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 cricket::AudioRecvParameters parameters;
827 parameters.codecs.push_back(kIsacCodec);
828 parameters.codecs.push_back(kPcmuCodec);
829 parameters.codecs.push_back(kOpusCodec);
830 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800831 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700832 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
833 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
834 {{0, {"PCMU", 8000, 1}},
835 {103, {"ISAC", 16000, 1}},
836 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839// Test that we can decode OPUS with stereo = 0.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
844 parameters.codecs.push_back(kPcmuCodec);
845 parameters.codecs.push_back(kOpusCodec);
846 parameters.codecs[2].params["stereo"] = "0";
847 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800848 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700849 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
850 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
851 {{0, {"PCMU", 8000, 1}},
852 {103, {"ISAC", 16000, 1}},
853 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854}
855
856// Test that we can decode OPUS with stereo = 1.
857TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700858 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200859 cricket::AudioRecvParameters parameters;
860 parameters.codecs.push_back(kIsacCodec);
861 parameters.codecs.push_back(kPcmuCodec);
862 parameters.codecs.push_back(kOpusCodec);
863 parameters.codecs[2].params["stereo"] = "1";
864 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800865 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700866 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
867 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
868 {{0, {"PCMU", 8000, 1}},
869 {103, {"ISAC", 16000, 1}},
870 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871}
872
873// Test that changes to recv codecs are applied to all streams.
874TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700875 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200876 cricket::AudioRecvParameters parameters;
877 parameters.codecs.push_back(kIsacCodec);
878 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800879 parameters.codecs.push_back(kTelephoneEventCodec1);
880 parameters.codecs.push_back(kTelephoneEventCodec2);
881 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200882 parameters.codecs[2].id = 126;
883 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700884 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
885 EXPECT_TRUE(AddRecvStream(ssrc));
886 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
887 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
888 {{0, {"PCMU", 8000, 1}},
889 {106, {"ISAC", 16000, 1}},
890 {126, {"telephone-event", 8000, 1}},
891 {107, {"telephone-event", 32000, 1}}})));
892 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893}
894
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800899 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901
solenberg2100c0b2017-03-01 11:29:29 -0800902 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200903 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800904 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905}
906
907// Test that we can apply the same set of codecs again while playing.
908TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700909 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200910 cricket::AudioRecvParameters parameters;
911 parameters.codecs.push_back(kIsacCodec);
912 parameters.codecs.push_back(kCn16000Codec);
913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700914 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
deadbeefcb383672017-04-26 16:28:42 -0700917 // Remapping a payload type to a different codec should fail.
918 parameters.codecs[0] = kOpusCodec;
919 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800921 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922}
923
924// Test that we can add a codec while playing.
925TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700926 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200927 cricket::AudioRecvParameters parameters;
928 parameters.codecs.push_back(kIsacCodec);
929 parameters.codecs.push_back(kCn16000Codec);
930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700931 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200933 parameters.codecs.push_back(kOpusCodec);
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800935 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936}
937
deadbeefcb383672017-04-26 16:28:42 -0700938// Test that we accept adding the same codec with a different payload type.
939// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
940TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
941 EXPECT_TRUE(SetupRecvStream());
942 cricket::AudioRecvParameters parameters;
943 parameters.codecs.push_back(kIsacCodec);
944 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
945
946 ++parameters.codecs[0].id;
947 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
948}
949
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000953 // Test that when autobw is enabled, bitrate is kept as the default
954 // value. autobw is enabled for the following tests because the target
955 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
957 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959
960 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700961 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
ossu20a4b3f2017-04-27 02:08:52 -0700963 // opus, default bitrate == 32000 in mono.
964 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965}
966
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000967TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700971 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
972 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700973 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
977 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
978 // Rates above the max (510000) should be capped.
979 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980}
981
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000982TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700983 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984
985 // Test that we can only set a maximum bitrate for a fixed-rate codec
986 // if it's bigger than the fixed rate.
987
988 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700989 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
991 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
995 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000996}
997
998TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700999 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001000 const int kDesiredBitrate = 128000;
1001 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001002 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001003 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001004 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001005
Yves Gerey665174f2018-06-19 15:03:05 +02001006 EXPECT_TRUE(
1007 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001008
solenberg2100c0b2017-03-01 11:29:29 -08001009 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001010}
1011
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012// Test that bitrate cannot be set for CBR codecs.
1013// Bitrate is ignored if it is higher than the fixed bitrate.
1014// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001015TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001016 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017
1018 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001019 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001020 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001021
1022 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001023 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001024 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001025
1026 send_parameters_.max_bandwidth_bps = 128;
1027 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001028 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029}
1030
skvlade0d46372016-04-07 22:59:22 -07001031// Test that the per-stream bitrate limit and the global
1032// bitrate limit both apply.
1033TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1034 EXPECT_TRUE(SetupSendStream());
1035
ossu20a4b3f2017-04-27 02:08:52 -07001036 // opus, default bitrate == 32000.
1037 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001038 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1039 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1040 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1041
1042 // CBR codecs allow both maximums to exceed the bitrate.
1043 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1044 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1045 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1046 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1047
1048 // CBR codecs don't allow per stream maximums to be too low.
1049 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1050 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1051}
1052
1053// Test that an attempt to set RtpParameters for a stream that does not exist
1054// fails.
1055TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1056 EXPECT_TRUE(SetupChannel());
1057 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001058 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001059 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001060
1061 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001062 EXPECT_FALSE(
1063 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001064}
1065
1066TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001067 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001068 // This test verifies that setting RtpParameters succeeds only if
1069 // the structure contains exactly one encoding.
1070 // TODO(skvlad): Update this test when we start supporting setting parameters
1071 // for each encoding individually.
1072
1073 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001074 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001075 // Two or more encodings should result in failure.
1076 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001077 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001078 // Zero encodings should also fail.
1079 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001080 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001081}
1082
1083// Changing the SSRC through RtpParameters is not allowed.
1084TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1085 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001086 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001087 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001088 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001089}
1090
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001092// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001093TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1094 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001095 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001096 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001097 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001098 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099 ASSERT_EQ(1u, parameters.encodings.size());
1100 ASSERT_TRUE(parameters.encodings[0].active);
1101 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001102 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001104
1105 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001106 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001107 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001108 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001109 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001110 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001111}
1112
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001113// Test that SetRtpSendParameters configures the correct encoding channel for
1114// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001115TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1116 SetupForMultiSendStream();
1117 // Create send streams.
1118 for (uint32_t ssrc : kSsrcs4) {
1119 EXPECT_TRUE(
1120 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1121 }
1122 // Configure one stream to be limited by the stream config, another to be
1123 // limited by the global max, and the third one with no per-stream limit
1124 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001125 SetGlobalMaxBitrate(kOpusCodec, 32000);
1126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001128 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1129
ossu20a4b3f2017-04-27 02:08:52 -07001130 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1131 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1132 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001133
1134 // Remove the global cap; the streams should switch to their respective
1135 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001136 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001137 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1138 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1139 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001140}
1141
Tim Haloun648d28a2018-10-18 16:52:22 -07001142// RTCRtpEncodingParameters.network_priority must be one of a few values
1143// derived from the default priority, corresponding to very-low, low, medium,
1144// or high.
1145TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1146 EXPECT_TRUE(SetupSendStream());
1147 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1148 EXPECT_EQ(1UL, parameters.encodings.size());
1149 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1150 parameters.encodings[0].network_priority);
1151
1152 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1153 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1154 for (auto it : good_values) {
1155 parameters.encodings[0].network_priority = it;
1156 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1157 }
1158 for (auto it : bad_values) {
1159 parameters.encodings[0].network_priority = it;
1160 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1161 }
1162}
1163
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164// Test that GetRtpSendParameters returns the currently configured codecs.
1165TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001166 EXPECT_TRUE(SetupSendStream());
1167 cricket::AudioSendParameters parameters;
1168 parameters.codecs.push_back(kIsacCodec);
1169 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001170 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001171
solenberg2100c0b2017-03-01 11:29:29 -08001172 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001173 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001174 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1175 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176}
1177
Florent Castellidacec712018-05-24 16:24:21 +02001178// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1179TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1180 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1181 params.cname = "rtcpcname";
1182 EXPECT_TRUE(SetupSendStream(params));
1183
1184 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1185 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1186}
1187
Florent Castelliabe301f2018-06-12 18:33:49 +02001188TEST_F(WebRtcVoiceEngineTestFake,
1189 DetectRtpSendParameterHeaderExtensionsChange) {
1190 EXPECT_TRUE(SetupSendStream());
1191
1192 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1193 rtp_parameters.header_extensions.emplace_back();
1194
1195 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1196
1197 webrtc::RTCError result =
1198 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1199 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1200}
1201
deadbeefcb443432016-12-12 11:12:36 -08001202// Test that GetRtpSendParameters returns an SSRC.
1203TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1204 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001205 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001206 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001207 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001208}
1209
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001210// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001211TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001212 EXPECT_TRUE(SetupSendStream());
1213 cricket::AudioSendParameters parameters;
1214 parameters.codecs.push_back(kIsacCodec);
1215 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001216 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001217
solenberg2100c0b2017-03-01 11:29:29 -08001218 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001219
1220 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001221 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001222
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001224 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1225 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001226}
1227
minyuececec102017-03-27 13:04:25 -07001228// Test that max_bitrate_bps in send stream config gets updated correctly when
1229// SetRtpSendParameters is called.
1230TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1231 webrtc::test::ScopedFieldTrials override_field_trials(
1232 "WebRTC-Audio-SendSideBwe/Enabled/");
1233 EXPECT_TRUE(SetupSendStream());
1234 cricket::AudioSendParameters send_parameters;
1235 send_parameters.codecs.push_back(kOpusCodec);
1236 SetSendParameters(send_parameters);
1237
1238 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1239 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1240 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1241
1242 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001243 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001244 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001245
1246 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1247 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1248}
1249
Seth Hampson24722b32017-12-22 09:36:42 -08001250// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1251// a value <= 0, setting the parameters returns false.
1252TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1253 EXPECT_TRUE(SetupSendStream());
1254 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1255 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1256 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1257 rtp_parameters.encodings[0].bitrate_priority);
1258
1259 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001260 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001261 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001262 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001263}
1264
1265// Test that the bitrate_priority in the send stream config gets updated when
1266// SetRtpSendParameters is set for the VoiceMediaChannel.
1267TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1268 EXPECT_TRUE(SetupSendStream());
1269 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1270
1271 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1272 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1273 rtp_parameters.encodings[0].bitrate_priority);
1274 double new_bitrate_priority = 2.0;
1275 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001276 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001277
1278 // The priority should get set for both the audio channel's rtp parameters
1279 // and the audio send stream's audio config.
1280 EXPECT_EQ(
1281 new_bitrate_priority,
1282 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1283 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1284}
1285
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001286// Test that GetRtpReceiveParameters returns the currently configured codecs.
1287TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1288 EXPECT_TRUE(SetupRecvStream());
1289 cricket::AudioRecvParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
1292 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1293
1294 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001295 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001296 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1297 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1298 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1299}
1300
deadbeefcb443432016-12-12 11:12:36 -08001301// Test that GetRtpReceiveParameters returns an SSRC.
1302TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1303 EXPECT_TRUE(SetupRecvStream());
1304 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001305 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001306 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001307 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001308}
1309
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001310// Test that if we set/get parameters multiple times, we get the same results.
1311TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
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 initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001319 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001320
1321 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001322 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001323
1324 // ... And this shouldn't change the params returned by
1325 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001326 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1327 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001328}
1329
deadbeef3bc15102017-04-20 19:25:07 -07001330// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1331// aren't signaled. It should return an empty "RtpEncodingParameters" when
1332// configured to receive an unsignaled stream and no packets have been received
1333// yet, and start returning the SSRC once a packet has been received.
1334TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1335 ASSERT_TRUE(SetupChannel());
1336 // Call necessary methods to configure receiving a default stream as
1337 // soon as it arrives.
1338 cricket::AudioRecvParameters parameters;
1339 parameters.codecs.push_back(kIsacCodec);
1340 parameters.codecs.push_back(kPcmuCodec);
1341 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1342
1343 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1344 // stream. Should return nothing.
1345 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1346
1347 // Set a sink for an unsignaled stream.
1348 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1349 // Value of "0" means "unsignaled stream".
1350 channel_->SetRawAudioSink(0, std::move(fake_sink));
1351
1352 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1353 // in this method means "unsignaled stream".
1354 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1355 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1356 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1357
1358 // Receive PCMU packet (SSRC=1).
1359 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1360
1361 // The |ssrc| member should still be unset.
1362 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1363 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1364 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1365}
1366
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001367// Test that we apply codecs properly.
1368TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001369 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 cricket::AudioSendParameters parameters;
1371 parameters.codecs.push_back(kIsacCodec);
1372 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001373 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001375 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001376 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001377 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1378 EXPECT_EQ(96, send_codec_spec.payload_type);
1379 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1380 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1381 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001382 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001383 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384}
1385
ossu20a4b3f2017-04-27 02:08:52 -07001386// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1387// AudioSendStream.
1388TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001389 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 cricket::AudioSendParameters parameters;
1391 parameters.codecs.push_back(kIsacCodec);
1392 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001393 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 parameters.codecs[0].id = 96;
1395 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001396 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001397 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001398 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001399 // Calling SetSendCodec again with same codec which is already set.
1400 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001401 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001402 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001403}
1404
ossu20a4b3f2017-04-27 02:08:52 -07001405// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1406// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001407
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001408// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001410 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 cricket::AudioSendParameters parameters;
1412 parameters.codecs.push_back(kOpusCodec);
1413 parameters.codecs[0].bitrate = 0;
1414 parameters.codecs[0].clockrate = 50000;
1415 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416}
1417
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001418// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 0;
1424 parameters.codecs[0].channels = 0;
1425 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001428// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001430 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 cricket::AudioSendParameters parameters;
1432 parameters.codecs.push_back(kOpusCodec);
1433 parameters.codecs[0].bitrate = 0;
1434 parameters.codecs[0].channels = 0;
1435 parameters.codecs[0].params["stereo"] = "1";
1436 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001437}
1438
1439// Test that if channel is 1 for opus and there's no stereo, we fail.
1440TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001441 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 cricket::AudioSendParameters parameters;
1443 parameters.codecs.push_back(kOpusCodec);
1444 parameters.codecs[0].bitrate = 0;
1445 parameters.codecs[0].channels = 1;
1446 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447}
1448
1449// Test that if channel is 1 for opus and stereo=0, we fail.
1450TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001451 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001452 cricket::AudioSendParameters parameters;
1453 parameters.codecs.push_back(kOpusCodec);
1454 parameters.codecs[0].bitrate = 0;
1455 parameters.codecs[0].channels = 1;
1456 parameters.codecs[0].params["stereo"] = "0";
1457 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458}
1459
1460// Test that if channel is 1 for opus and stereo=1, we fail.
1461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].bitrate = 0;
1466 parameters.codecs[0].channels = 1;
1467 parameters.codecs[0].params["stereo"] = "1";
1468 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469}
1470
ossu20a4b3f2017-04-27 02:08:52 -07001471// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001473 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001474 cricket::AudioSendParameters parameters;
1475 parameters.codecs.push_back(kOpusCodec);
1476 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001478 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479}
1480
ossu20a4b3f2017-04-27 02:08:52 -07001481// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001483 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 cricket::AudioSendParameters parameters;
1485 parameters.codecs.push_back(kOpusCodec);
1486 parameters.codecs[0].bitrate = 0;
1487 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001488 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001489 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490}
1491
ossu20a4b3f2017-04-27 02:08:52 -07001492// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001493TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001494 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 cricket::AudioSendParameters parameters;
1496 parameters.codecs.push_back(kOpusCodec);
1497 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001498 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001500 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001501 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001502
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001504 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001505 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001506}
1507
ossu20a4b3f2017-04-27 02:08:52 -07001508// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 cricket::AudioSendParameters parameters;
1512 parameters.codecs.push_back(kOpusCodec);
1513 parameters.codecs[0].bitrate = 0;
1514 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001515 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001516 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517}
1518
ossu20a4b3f2017-04-27 02:08:52 -07001519// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001520TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001521 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 cricket::AudioSendParameters parameters;
1523 parameters.codecs.push_back(kOpusCodec);
1524 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001525 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001526 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001527 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001528 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001529
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001530 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001531 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001532 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001533}
1534
ossu20a4b3f2017-04-27 02:08:52 -07001535// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001536TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001537 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001538 cricket::AudioSendParameters parameters;
1539 parameters.codecs.push_back(kOpusCodec);
1540 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001542 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1543 EXPECT_EQ(111, spec.payload_type);
1544 EXPECT_EQ(96000, spec.target_bitrate_bps);
1545 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001546 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001547 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548}
1549
ossu20a4b3f2017-04-27 02:08:52 -07001550// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].bitrate = 30000;
1556 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001558 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
ossu20a4b3f2017-04-27 02:08:52 -07001561// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001567 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001568 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569}
1570
ossu20a4b3f2017-04-27 02:08:52 -07001571// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001573 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001574 cricket::AudioSendParameters parameters;
1575 parameters.codecs.push_back(kOpusCodec);
1576 parameters.codecs[0].bitrate = 30000;
1577 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001579 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001580}
1581
stefan13f1a0a2016-11-30 07:22:58 -08001582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1583 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1584 200000);
1585}
1586
1587TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1588 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1589}
1590
1591TEST_F(WebRtcVoiceEngineTestFake,
1592 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1593 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1594}
1595
1596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1597 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1598}
1599
Yves Gerey665174f2018-06-19 15:03:05 +02001600TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001601 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1602 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001603 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001604 // Setting max bitrate should keep previous min bitrate
1605 // Setting max bitrate should not reset start bitrate.
1606 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1607 SetSdpBitrateParameters(
1608 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1609 Field(&BitrateConstraints::start_bitrate_bps, -1),
1610 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001611 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001612}
1613
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001614// Test that we can enable NACK with opus as caller.
1615TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 cricket::AudioSendParameters parameters;
1618 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001619 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1620 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001621 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624}
1625
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001626// Test that we can enable NACK with opus as callee.
1627TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001628 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 cricket::AudioSendParameters parameters;
1630 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001631 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1632 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001633 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001635 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001636 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001637
Yves Gerey665174f2018-06-19 15:03:05 +02001638 EXPECT_TRUE(
1639 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001640 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001641}
1642
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643// Test that we can enable NACK on receive streams.
1644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001646 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001647 cricket::AudioSendParameters parameters;
1648 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001649 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1650 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001651 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1652 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1655 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656}
1657
1658// Test that we can disable NACK.
1659TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001660 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001661 cricket::AudioSendParameters parameters;
1662 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001663 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1664 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001668 parameters.codecs.clear();
1669 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001670 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001671 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672}
1673
1674// Test that we can disable NACK on receive streams.
1675TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001676 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001677 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters parameters;
1679 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001680 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1681 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1684 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001686 parameters.codecs.clear();
1687 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001688 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001689 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1690 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001691}
1692
1693// Test that NACK is enabled on a new receive stream.
1694TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001695 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001696 cricket::AudioSendParameters parameters;
1697 parameters.codecs.push_back(kIsacCodec);
1698 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001699 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1700 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001702 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703
solenberg2100c0b2017-03-01 11:29:29 -08001704 EXPECT_TRUE(AddRecvStream(kSsrcY));
1705 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1706 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1707 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001708}
1709
stefanba4c0e42016-02-04 04:12:24 -08001710TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001711 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001712 cricket::AudioSendParameters send_parameters;
1713 send_parameters.codecs.push_back(kOpusCodec);
1714 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001716
1717 cricket::AudioRecvParameters recv_parameters;
1718 recv_parameters.codecs.push_back(kIsacCodec);
1719 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001720 EXPECT_TRUE(AddRecvStream(kSsrcX));
1721 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001722 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001723 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001724
ossudedfd282016-06-14 07:12:39 -07001725 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001727 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001728 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001729 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001730}
1731
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001732// Test that we can switch back and forth between Opus and ISAC with CN.
1733TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001734 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001735
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 cricket::AudioSendParameters opus_parameters;
1737 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001739 {
ossu20a4b3f2017-04-27 02:08:52 -07001740 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1741 EXPECT_EQ(111, spec.payload_type);
1742 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001743 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 cricket::AudioSendParameters isac_parameters;
1746 isac_parameters.codecs.push_back(kIsacCodec);
1747 isac_parameters.codecs.push_back(kCn16000Codec);
1748 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001750 {
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(103, spec.payload_type);
1753 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755
solenberg059fb442016-10-26 05:12:24 -07001756 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001757 {
ossu20a4b3f2017-04-27 02:08:52 -07001758 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1759 EXPECT_EQ(111, spec.payload_type);
1760 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001761 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001762}
1763
1764// Test that we handle various ways of specifying bitrate.
1765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001770 {
ossu20a4b3f2017-04-27 02:08:52 -07001771 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1772 EXPECT_EQ(103, spec.payload_type);
1773 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1774 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001775 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776
Yves Gerey665174f2018-06-19 15:03:05 +02001777 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001778 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001779 {
ossu20a4b3f2017-04-27 02:08:52 -07001780 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1781 EXPECT_EQ(103, spec.payload_type);
1782 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1783 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001784 }
Yves Gerey665174f2018-06-19 15:03:05 +02001785 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001787 {
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(103, spec.payload_type);
1790 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1791 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001792 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793
Yves Gerey665174f2018-06-19 15:03:05 +02001794 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001795 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001796 {
ossu20a4b3f2017-04-27 02:08:52 -07001797 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1798 EXPECT_EQ(0, spec.payload_type);
1799 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1800 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001801 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001802
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(0, spec.payload_type);
1808 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1809 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001810 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001813 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001814 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001815 {
ossu20a4b3f2017-04-27 02:08:52 -07001816 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1817 EXPECT_EQ(111, spec.payload_type);
1818 EXPECT_STREQ("opus", spec.format.name.c_str());
1819 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001820 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001821}
1822
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001823// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001825 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 cricket::AudioSendParameters parameters;
1827 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001828}
1829
1830// Test that we can set send codecs even with telephone-event codec as the first
1831// one on the list.
1832TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001833 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001835 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs.push_back(kIsacCodec);
1837 parameters.codecs.push_back(kPcmuCodec);
1838 parameters.codecs[0].id = 98; // DTMF
1839 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001841 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1842 EXPECT_EQ(96, spec.payload_type);
1843 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001844 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001845 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001846}
1847
Harald Alvestranda1f66612018-02-21 11:24:23 +01001848// Test that CanInsertDtmf() is governed by the send flag
1849TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1850 EXPECT_TRUE(SetupSendStream());
1851 cricket::AudioSendParameters parameters;
1852 parameters.codecs.push_back(kTelephoneEventCodec1);
1853 parameters.codecs.push_back(kPcmuCodec);
1854 parameters.codecs[0].id = 98; // DTMF
1855 parameters.codecs[1].id = 96;
1856 SetSendParameters(parameters);
1857 EXPECT_FALSE(channel_->CanInsertDtmf());
1858 SetSend(true);
1859 EXPECT_TRUE(channel_->CanInsertDtmf());
1860 SetSend(false);
1861 EXPECT_FALSE(channel_->CanInsertDtmf());
1862}
1863
solenberg31642aa2016-03-14 08:00:37 -07001864// Test that payload type range is limited for telephone-event codec.
1865TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001866 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001867 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001868 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001869 parameters.codecs.push_back(kIsacCodec);
1870 parameters.codecs[0].id = 0; // DTMF
1871 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001873 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001874 EXPECT_TRUE(channel_->CanInsertDtmf());
1875 parameters.codecs[0].id = 128; // DTMF
1876 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1877 EXPECT_FALSE(channel_->CanInsertDtmf());
1878 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001879 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001880 EXPECT_TRUE(channel_->CanInsertDtmf());
1881 parameters.codecs[0].id = -1; // DTMF
1882 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1883 EXPECT_FALSE(channel_->CanInsertDtmf());
1884}
1885
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001886// Test that we can set send codecs even with CN codec as the first
1887// one on the list.
1888TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001889 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 cricket::AudioSendParameters parameters;
1891 parameters.codecs.push_back(kCn16000Codec);
1892 parameters.codecs.push_back(kIsacCodec);
1893 parameters.codecs.push_back(kPcmuCodec);
1894 parameters.codecs[0].id = 98; // wideband CN
1895 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001896 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001897 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1898 EXPECT_EQ(96, send_codec_spec.payload_type);
1899 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001900 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901}
1902
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001903// Test that we set VAD and DTMF types correctly as caller.
1904TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001905 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 cricket::AudioSendParameters parameters;
1907 parameters.codecs.push_back(kIsacCodec);
1908 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001909 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001910 parameters.codecs.push_back(kCn16000Codec);
1911 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001912 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001913 parameters.codecs[0].id = 96;
1914 parameters.codecs[2].id = 97; // wideband CN
1915 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001916 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001917 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1918 EXPECT_EQ(96, send_codec_spec.payload_type);
1919 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001920 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001921 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001922 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001923 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001924}
1925
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001926// Test that we set VAD and DTMF types correctly as callee.
1927TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001928 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 cricket::AudioSendParameters parameters;
1930 parameters.codecs.push_back(kIsacCodec);
1931 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001932 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001933 parameters.codecs.push_back(kCn16000Codec);
1934 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001935 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001936 parameters.codecs[0].id = 96;
1937 parameters.codecs[2].id = 97; // wideband CN
1938 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001939 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001940 EXPECT_TRUE(
1941 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001942
ossu20a4b3f2017-04-27 02:08:52 -07001943 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1944 EXPECT_EQ(96, send_codec_spec.payload_type);
1945 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001946 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001947 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001948 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001949 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001950}
1951
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001952// Test that we only apply VAD if we have a CN codec that matches the
1953// send codec clockrate.
1954TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001955 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001956 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs.push_back(kIsacCodec);
1959 parameters.codecs.push_back(kCn16000Codec);
1960 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001962 {
ossu20a4b3f2017-04-27 02:08:52 -07001963 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1964 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001965 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001966 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001967 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001971 {
ossu20a4b3f2017-04-27 02:08:52 -07001972 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1973 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001974 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001975 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001979 {
ossu20a4b3f2017-04-27 02:08:52 -07001980 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1981 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001982 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001983 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001984 }
Brave Yao5225dd82015-03-26 07:39:19 +08001985 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001986 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001987 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001988 {
ossu20a4b3f2017-04-27 02:08:52 -07001989 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1990 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001991 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001992 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001993}
1994
1995// Test that we perform case-insensitive matching of codec names.
1996TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001997 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001998 cricket::AudioSendParameters parameters;
1999 parameters.codecs.push_back(kIsacCodec);
2000 parameters.codecs.push_back(kPcmuCodec);
2001 parameters.codecs.push_back(kCn16000Codec);
2002 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002003 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002004 parameters.codecs[0].name = "iSaC";
2005 parameters.codecs[0].id = 96;
2006 parameters.codecs[2].id = 97; // wideband CN
2007 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002008 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002009 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2010 EXPECT_EQ(96, send_codec_spec.payload_type);
2011 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002012 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002013 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002014 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002015 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002016}
2017
stefanba4c0e42016-02-04 04:12:24 -08002018class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2019 public:
2020 WebRtcVoiceEngineWithSendSideBweTest()
2021 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2022};
2023
2024TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2025 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002026 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002027 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002028 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2029 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2030 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002031 extension.id);
2032 return;
2033 }
2034 }
2035 FAIL() << "Transport sequence number extension not in header-extension list.";
2036}
2037
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002038// Test support for audio level header extension.
2039TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002040 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002041}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002042TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002043 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002044}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002045
solenbergd4adce42016-11-17 06:26:52 -08002046// Test support for transport sequence number header extension.
2047TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2048 TestSetSendRtpHeaderExtensions(
2049 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050}
solenbergd4adce42016-11-17 06:26:52 -08002051TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2052 TestSetRecvRtpHeaderExtensions(
2053 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002054}
2055
solenberg1ac56142015-10-13 03:58:19 -07002056// Test that we can create a channel and start sending on it.
2057TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002058 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002059 SetSendParameters(send_parameters_);
2060 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002061 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002062 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002063 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002064}
2065
2066// Test that a channel will send if and only if it has a source and is enabled
2067// for sending.
2068TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002069 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002070 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002071 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002072 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002073 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2074 SetAudioSend(kSsrcX, true, &fake_source_);
2075 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2076 SetAudioSend(kSsrcX, true, nullptr);
2077 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002078}
2079
solenberg94218532016-06-16 10:53:22 -07002080// Test that a channel is muted/unmuted.
2081TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2082 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002084 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2085 SetAudioSend(kSsrcX, true, nullptr);
2086 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2087 SetAudioSend(kSsrcX, false, nullptr);
2088 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002089}
2090
solenberg6d6e7c52016-04-13 09:07:30 -07002091// Test that SetSendParameters() does not alter a stream's send state.
2092TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2093 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002094 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002095
2096 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002097 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002098 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002099
2100 // Changing RTP header extensions will recreate the AudioSendStream.
2101 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002102 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002103 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105
2106 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002107 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002108 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002109
2110 // Changing RTP header extensions will recreate the AudioSendStream.
2111 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002112 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002113 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002114}
2115
solenberg1ac56142015-10-13 03:58:19 -07002116// Test that we can create a channel and start playing out on it.
2117TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002118 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002119 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002120 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002121 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002122 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002123 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002124}
2125
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126// Test that we can add and remove send streams.
2127TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2128 SetupForMultiSendStream();
2129
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002131 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132
solenbergc96df772015-10-21 13:01:53 -07002133 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002134 EXPECT_TRUE(
2135 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002136 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002138 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 }
tfarina5237aaf2015-11-10 23:44:30 -08002140 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141
solenbergc96df772015-10-21 13:01:53 -07002142 // Delete the send streams.
2143 for (uint32_t ssrc : kSsrcs4) {
2144 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002145 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002146 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147 }
solenbergc96df772015-10-21 13:01:53 -07002148 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149}
2150
2151// Test SetSendCodecs correctly configure the codecs in all send streams.
2152TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2153 SetupForMultiSendStream();
2154
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002156 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002157 EXPECT_TRUE(
2158 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002159 }
2160
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002163 parameters.codecs.push_back(kIsacCodec);
2164 parameters.codecs.push_back(kCn16000Codec);
2165 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002166 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002167
2168 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002169 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002170 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2171 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002172 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2173 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002174 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002175 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176 }
2177
minyue7a973442016-10-20 03:27:12 -07002178 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002179 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002180 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002181 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002182 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2183 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002184 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2185 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002186 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002187 }
2188}
2189
2190// Test we can SetSend on all send streams correctly.
2191TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2192 SetupForMultiSendStream();
2193
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002194 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002195 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002196 EXPECT_TRUE(
2197 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002198 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002199 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002200 }
2201
2202 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002203 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002204 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002205 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002206 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207 }
2208
2209 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002210 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002211 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002213 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002214 }
2215}
2216
2217// Test we can set the correct statistics on all send streams.
2218TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2219 SetupForMultiSendStream();
2220
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002222 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002223 EXPECT_TRUE(
2224 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002225 }
solenberg85a04962015-10-27 03:35:21 -07002226
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002227 // Create a receive stream to check that none of the send streams end up in
2228 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002230
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002232 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002233 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002234 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002235
solenberg85a04962015-10-27 03:35:21 -07002236 // Check stats for the added streams.
2237 {
2238 cricket::VoiceMediaInfo info;
2239 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002240
solenberg85a04962015-10-27 03:35:21 -07002241 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002242 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002243 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002244 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002245 }
hbos1acfbd22016-11-17 23:43:29 -08002246 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002247
2248 // We have added one receive stream. We should see empty stats.
2249 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002250 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002251 }
solenberg1ac56142015-10-13 03:58:19 -07002252
solenberg2100c0b2017-03-01 11:29:29 -08002253 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002254 {
2255 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002256 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002257 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002258 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002259 EXPECT_EQ(0u, info.receivers.size());
2260 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002261
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002262 // Deliver a new packet - a default receive stream should be created and we
2263 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002264 {
2265 cricket::VoiceMediaInfo info;
2266 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2267 SetAudioReceiveStreamStats();
2268 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002269 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002270 EXPECT_EQ(1u, info.receivers.size());
2271 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002272 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002273 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002274}
2275
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002276// Test that we can add and remove receive streams, and do proper send/playout.
2277// We can receive on multiple streams while sending one stream.
2278TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002279 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002280
solenberg1ac56142015-10-13 03:58:19 -07002281 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002282 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002283 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284
solenberg1ac56142015-10-13 03:58:19 -07002285 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002287 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002288 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002289
solenberg1ac56142015-10-13 03:58:19 -07002290 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002291 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
2293 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2295 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2296 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002297
2298 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002299 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002301
2302 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002303 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002304 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2305 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002306
aleloi84ef6152016-08-04 05:28:21 -07002307 // Restart playout and make sure recv streams are played out.
2308 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002309 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2310 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002311
aleloi84ef6152016-08-04 05:28:21 -07002312 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002313 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2314 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002315}
2316
wu@webrtc.org97077a32013-10-25 21:18:33 +00002317TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002318 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002319 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2320 .Times(1)
2321 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002322 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2323 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002324 send_parameters_.options.tx_agc_target_dbov = 3;
2325 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2326 send_parameters_.options.tx_agc_limiter = true;
2327 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002328 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2329 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2330 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002331 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002332}
2333
minyue6b825df2016-10-31 04:08:32 -07002334TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2335 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002336 send_parameters_.options.audio_network_adaptor = true;
2337 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002338 SetSendParameters(send_parameters_);
2339 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002340 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002341}
2342
2343TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2344 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002345 send_parameters_.options.audio_network_adaptor = true;
2346 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002347 SetSendParameters(send_parameters_);
2348 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002349 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002350 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002351 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002352 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002353 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002354}
2355
2356TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2357 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002358 send_parameters_.options.audio_network_adaptor = true;
2359 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002360 SetSendParameters(send_parameters_);
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 const int initial_num = call_.GetNumCreatedSendStreams();
2364 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002365 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002366 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2367 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002368 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002369 // AudioSendStream not expected to be recreated.
2370 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2371 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002372 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002373}
2374
michaelt6672b262017-01-11 10:17:59 -08002375class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2376 : public WebRtcVoiceEngineTestFake {
2377 public:
2378 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2379 : WebRtcVoiceEngineTestFake(
2380 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2381 "Enabled/") {}
2382};
2383
2384TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2385 EXPECT_TRUE(SetupSendStream());
2386 cricket::AudioSendParameters parameters;
2387 parameters.codecs.push_back(kOpusCodec);
2388 SetSendParameters(parameters);
2389 const int initial_num = call_.GetNumCreatedSendStreams();
2390 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2391
2392 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2393 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002394 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2395 constexpr int kMinOverheadBps =
2396 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002397
2398 constexpr int kOpusMinBitrateBps = 6000;
2399 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002400 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002401 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002402 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002403 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002404
Oskar Sundbom78807582017-11-16 11:09:55 +01002405 parameters.options.audio_network_adaptor = true;
2406 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002407 SetSendParameters(parameters);
2408
ossu11bfc532017-02-16 05:37:06 -08002409 constexpr int kMinOverheadWithAnaBps =
2410 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002411
2412 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002413 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002414
minyuececec102017-03-27 13:04:25 -07002415 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002416 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002417}
2418
minyuececec102017-03-27 13:04:25 -07002419// This test is similar to
2420// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2421// additional field trial.
2422TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2423 SetRtpSendParameterUpdatesMaxBitrate) {
2424 EXPECT_TRUE(SetupSendStream());
2425 cricket::AudioSendParameters send_parameters;
2426 send_parameters.codecs.push_back(kOpusCodec);
2427 SetSendParameters(send_parameters);
2428
2429 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2430 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2431 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2432
2433 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002434 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002435 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002436
2437 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2438#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2439 constexpr int kMinOverhead = 3333;
2440#else
2441 constexpr int kMinOverhead = 6666;
2442#endif
2443 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2444}
2445
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002447// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002449 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002450 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451}
2452
2453TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2454 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002455 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002456 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002457 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002458 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002459 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002460 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002461 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462
solenberg85a04962015-10-27 03:35:21 -07002463 // Check stats for the added streams.
2464 {
2465 cricket::VoiceMediaInfo info;
2466 EXPECT_EQ(true, channel_->GetStats(&info));
2467
2468 // We have added one send stream. We should see the stats we've set.
2469 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002470 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002471 // We have added one receive stream. We should see empty stats.
2472 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002473 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002474 }
solenberg1ac56142015-10-13 03:58:19 -07002475
solenberg566ef242015-11-06 15:34:49 -08002476 // Start sending - this affects some reported stats.
2477 {
2478 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002479 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002480 EXPECT_EQ(true, channel_->GetStats(&info));
2481 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002482 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002483 }
2484
solenberg2100c0b2017-03-01 11:29:29 -08002485 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002486 {
2487 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002489 EXPECT_EQ(true, channel_->GetStats(&info));
2490 EXPECT_EQ(1u, info.senders.size());
2491 EXPECT_EQ(0u, info.receivers.size());
2492 }
solenberg1ac56142015-10-13 03:58:19 -07002493
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002494 // Deliver a new packet - a default receive stream should be created and we
2495 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002496 {
2497 cricket::VoiceMediaInfo info;
2498 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2499 SetAudioReceiveStreamStats();
2500 EXPECT_EQ(true, channel_->GetStats(&info));
2501 EXPECT_EQ(1u, info.senders.size());
2502 EXPECT_EQ(1u, info.receivers.size());
2503 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002504 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002505 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506}
2507
2508// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002509// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002511 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002512 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2513 EXPECT_TRUE(AddRecvStream(kSsrcY));
2514 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002515}
2516
2517// Test that the local SSRC is the same on sending and receiving channels if the
2518// receive channel is created before the send channel.
2519TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002520 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002522 EXPECT_TRUE(
2523 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002524 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2525 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526}
2527
2528// Test that we can properly receive packets.
2529TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002530 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002531 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002532 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002533
Yves Gerey665174f2018-06-19 15:03:05 +02002534 EXPECT_TRUE(
2535 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002536}
2537
2538// Test that we can properly receive packets on multiple streams.
2539TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002540 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002541 const uint32_t ssrc1 = 1;
2542 const uint32_t ssrc2 = 2;
2543 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002544 EXPECT_TRUE(AddRecvStream(ssrc1));
2545 EXPECT_TRUE(AddRecvStream(ssrc2));
2546 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002547 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002548 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002549 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002551 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002552 }
mflodman3d7db262016-04-29 00:57:13 -07002553
2554 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2555 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2556 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2557
2558 EXPECT_EQ(s1.received_packets(), 0);
2559 EXPECT_EQ(s2.received_packets(), 0);
2560 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002561
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002562 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002563 EXPECT_EQ(s1.received_packets(), 0);
2564 EXPECT_EQ(s2.received_packets(), 0);
2565 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002566
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002567 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002568 EXPECT_EQ(s1.received_packets(), 1);
2569 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2570 EXPECT_EQ(s2.received_packets(), 0);
2571 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002572
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002573 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002574 EXPECT_EQ(s1.received_packets(), 1);
2575 EXPECT_EQ(s2.received_packets(), 1);
2576 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2577 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002578
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002579 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002580 EXPECT_EQ(s1.received_packets(), 1);
2581 EXPECT_EQ(s2.received_packets(), 1);
2582 EXPECT_EQ(s3.received_packets(), 1);
2583 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002584
mflodman3d7db262016-04-29 00:57:13 -07002585 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2586 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2587 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002588}
2589
solenberg2100c0b2017-03-01 11:29:29 -08002590// Test that receiving on an unsignaled stream works (a stream is created).
2591TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002592 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002593 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002594
solenberg7e63ef02015-11-20 00:19:43 -08002595 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002596
Mirko Bonadeif859e552018-05-30 15:31:29 +02002597 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002598 EXPECT_TRUE(
2599 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002600}
2601
Seth Hampson5897a6e2018-04-03 11:16:33 -07002602// Tests that when we add a stream without SSRCs, but contains a stream_id
2603// that it is stored and its stream id is later used when the first packet
2604// arrives to properly create a receive stream with a sync label.
2605TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2606 const char kSyncLabel[] = "sync_label";
2607 EXPECT_TRUE(SetupChannel());
2608 cricket::StreamParams unsignaled_stream;
2609 unsignaled_stream.set_stream_ids({kSyncLabel});
2610 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2611 // The stream shouldn't have been created at this point because it doesn't
2612 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002613 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002614
2615 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2616
Mirko Bonadeif859e552018-05-30 15:31:29 +02002617 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002618 EXPECT_TRUE(
2619 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2620 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2621
2622 // Removing the unsignaled stream clears the cached parameters. If a new
2623 // default unsignaled receive stream is created it will not have a sync group.
2624 channel_->RemoveRecvStream(0);
2625 channel_->RemoveRecvStream(kSsrc1);
2626
2627 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2628
Mirko Bonadeif859e552018-05-30 15:31:29 +02002629 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002630 EXPECT_TRUE(
2631 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2632 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2633}
2634
solenberg2100c0b2017-03-01 11:29:29 -08002635// Test that receiving N unsignaled stream works (streams will be created), and
2636// that packets are forwarded to them all.
2637TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002638 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002639 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002640 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2641
solenberg2100c0b2017-03-01 11:29:29 -08002642 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002643 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002644 rtc::SetBE32(&packet[8], ssrc);
2645 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002646
solenberg2100c0b2017-03-01 11:29:29 -08002647 // Verify we have one new stream for each loop iteration.
2648 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002649 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2650 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002651 }
mflodman3d7db262016-04-29 00:57:13 -07002652
solenberg2100c0b2017-03-01 11:29:29 -08002653 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002654 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002655 rtc::SetBE32(&packet[8], ssrc);
2656 DeliverPacket(packet, sizeof(packet));
2657
solenbergebb349d2017-03-13 05:46:15 -07002658 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002659 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2660 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2661 }
2662
2663 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2664 constexpr uint32_t kAnotherSsrc = 667;
2665 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002666 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002667
2668 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002669 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002670 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002671 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002672 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2673 EXPECT_EQ(2, streams[i]->received_packets());
2674 }
2675 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2676 EXPECT_EQ(1, streams[i]->received_packets());
2677 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002678 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002679}
2680
solenberg2100c0b2017-03-01 11:29:29 -08002681// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002682// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002683TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002684 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002685 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002686 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2687
2688 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002689 const uint32_t signaled_ssrc = 1;
2690 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002691 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002692 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002693 EXPECT_TRUE(
2694 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002695 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002696
2697 // Note that the first unknown SSRC cannot be 0, because we only support
2698 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002699 const uint32_t unsignaled_ssrc = 7011;
2700 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002701 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002702 EXPECT_TRUE(
2703 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002704 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002705
2706 DeliverPacket(packet, sizeof(packet));
2707 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2708
2709 rtc::SetBE32(&packet[8], signaled_ssrc);
2710 DeliverPacket(packet, sizeof(packet));
2711 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002712 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002713}
2714
solenberg4904fb62017-02-17 12:01:14 -08002715// Two tests to verify that adding a receive stream with the same SSRC as a
2716// previously added unsignaled stream will only recreate underlying stream
2717// objects if the stream parameters have changed.
2718TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2719 EXPECT_TRUE(SetupChannel());
2720
2721 // Spawn unsignaled stream with SSRC=1.
2722 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002723 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002724 EXPECT_TRUE(
2725 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002726
2727 // Verify that the underlying stream object in Call is not recreated when a
2728 // stream with SSRC=1 is added.
2729 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002730 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002731 int audio_receive_stream_id = streams.front()->id();
2732 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002733 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002734 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2735}
2736
2737TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2738 EXPECT_TRUE(SetupChannel());
2739
2740 // Spawn unsignaled stream with SSRC=1.
2741 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002742 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002743 EXPECT_TRUE(
2744 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002745
2746 // Verify that the underlying stream object in Call *is* recreated when a
2747 // stream with SSRC=1 is added, and which has changed stream parameters.
2748 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002749 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002750 int audio_receive_stream_id = streams.front()->id();
2751 cricket::StreamParams stream_params;
2752 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002753 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002754 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002755 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002756 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2757}
2758
solenberg1ac56142015-10-13 03:58:19 -07002759// Test that AddRecvStream creates new stream.
2760TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002761 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002762 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002763}
2764
2765// Test that after adding a recv stream, we do not decode more codecs than
2766// those previously passed into SetRecvCodecs.
2767TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002768 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002769 cricket::AudioRecvParameters parameters;
2770 parameters.codecs.push_back(kIsacCodec);
2771 parameters.codecs.push_back(kPcmuCodec);
2772 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002773 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002774 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2775 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2776 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002777}
2778
2779// Test that we properly clean up any streams that were added, even if
2780// not explicitly removed.
2781TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002782 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002783 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002784 EXPECT_TRUE(AddRecvStream(1));
2785 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002786
Mirko Bonadeif859e552018-05-30 15:31:29 +02002787 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2788 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789 delete channel_;
2790 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002791 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2792 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793}
2794
wu@webrtc.org78187522013-10-07 23:32:02 +00002795TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002796 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002797 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002798}
2799
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002800TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002801 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002802 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002803 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002804}
2805
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002806// Test the InsertDtmf on default send stream as caller.
2807TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002808 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002809}
2810
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002811// Test the InsertDtmf on default send stream as callee
2812TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002813 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002814}
2815
2816// Test the InsertDtmf on specified send stream as caller.
2817TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002818 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002819}
2820
2821// Test the InsertDtmf on specified send stream as callee.
2822TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002823 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824}
2825
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002826TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002827 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002828 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002829 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2830 .Times(9)
2831 .WillRepeatedly(Return(false));
2832 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2833 .Times(4)
2834 .WillRepeatedly(Return(false));
2835 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2836 .Times(2)
2837 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002838
Mirko Bonadeif859e552018-05-30 15:31:29 +02002839 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002840 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002841
solenberg246b8172015-12-08 09:50:23 -08002842 // Nothing set in AudioOptions, so everything should be as default.
2843 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002844 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002845 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002846 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002847 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002848 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849
2850 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002851 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002852 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002853 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002854
2855 // Turn echo cancellation back on, with settings, and make sure
2856 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002857 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002858 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002859 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002861 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2862 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002863 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002864 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002865 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002866
2867 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002868 send_parameters_.options.delay_agnostic_aec = false;
2869 send_parameters_.options.extended_filter_aec = false;
2870 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002871 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002872 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002873
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002874 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002875 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002876 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002877 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002878
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002880 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002881 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002882 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002883 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002884 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002885
2886 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002889 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002890 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002891 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002893 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002894 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002896 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2898 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002899 send_parameters_.options.noise_suppression = false;
2900 send_parameters_.options.highpass_filter = false;
2901 send_parameters_.options.typing_detection = false;
2902 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002903 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002904 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002905 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906
solenberg1ac56142015-10-13 03:58:19 -07002907 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002908 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002909 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002910 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002913 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002914 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915}
2916
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002918 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002919 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2920 .Times(8)
2921 .WillRepeatedly(Return(false));
2922 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2923 .Times(8)
2924 .WillRepeatedly(Return(false));
2925 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2926 .Times(8)
2927 .WillRepeatedly(Return(false));
2928 EXPECT_CALL(adm_, RecordingIsInitialized())
2929 .Times(2)
2930 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002931 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2932 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002933 webrtc::AudioProcessing::Config apm_config;
2934 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002935 .WillRepeatedly(ReturnPointee(&apm_config));
2936 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002937 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002938 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002939
kwiberg686a8ef2016-02-26 03:00:35 -08002940 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002941 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002942 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2943 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002944 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002945 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002946 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2947 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002948
2949 // Have to add a stream to make SetSend work.
2950 cricket::StreamParams stream1;
2951 stream1.ssrcs.push_back(1);
2952 channel1->AddSendStream(stream1);
2953 cricket::StreamParams stream2;
2954 stream2.ssrcs.push_back(2);
2955 channel2->AddSendStream(stream2);
2956
2957 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002958 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002959 parameters_options_all.options.echo_cancellation = true;
2960 parameters_options_all.options.auto_gain_control = true;
2961 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002962 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002963 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002964 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002965 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002966 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002967 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002968 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002969 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002970 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002971 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972
2973 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002974 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002975 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002976 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002977 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002980 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002981 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002982 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002983 expected_options.echo_cancellation = true;
2984 expected_options.auto_gain_control = true;
2985 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002986 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987
2988 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002989 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002990 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002991 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002992 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002993 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002994 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002995 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002996 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01002997 expected_options.echo_cancellation = true;
2998 expected_options.auto_gain_control = false;
2999 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003000 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003002 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003003 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003004 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003005 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003006 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003007 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003009 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003010 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003011 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003012 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003013 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003014 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003016 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003017 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003018 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003019 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003020 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003021 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003024 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3025 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003026 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3027 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003028 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003029 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003030 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003031 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003032 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003033 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003034 expected_options.echo_cancellation = true;
3035 expected_options.auto_gain_control = false;
3036 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003037 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003038}
3039
wu@webrtc.orgde305012013-10-31 15:40:38 +00003040// This test verifies DSCP settings are properly applied on voice media channel.
3041TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003042 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003043 cricket::FakeNetworkInterface network_interface;
3044 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003045 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003046 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003047
peahb1c9d1d2017-07-25 15:45:24 -07003048 webrtc::AudioProcessing::Config apm_config;
3049 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003050 .WillRepeatedly(ReturnPointee(&apm_config));
3051 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003052 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003053 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003054
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003055 channel.reset(
3056 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3057 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003058 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003059 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3060 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3061
3062 config.enable_dscp = true;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003063 channel.reset(
3064 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3065 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003066 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003067 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3068
3069 // Create a send stream to configure
3070 EXPECT_TRUE(
3071 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3072 parameters = channel->GetRtpSendParameters(kSsrcZ);
3073 ASSERT_FALSE(parameters.encodings.empty());
3074
3075 // Various priorities map to various dscp values.
3076 parameters.encodings[0].network_priority = 4.0;
3077 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003078 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003079 parameters.encodings[0].network_priority = 0.5;
3080 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3081 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3082
3083 // A bad priority does not change the dscp value.
3084 parameters.encodings[0].network_priority = 0.0;
3085 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3086 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003087
Tim Haloun6ca98362018-09-17 17:06:08 -07003088 // Packets should also self-identify their dscp in PacketOptions.
3089 const uint8_t kData[10] = {0};
3090 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003091 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003092
nisse51542be2016-02-12 02:27:06 -08003093 // Verify that setting the option to false resets the
3094 // DiffServCodePoint.
3095 config.enable_dscp = false;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003096 channel.reset(
3097 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3098 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003099 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003100 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3101 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3102
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003103 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003104}
3105
solenberg4bac9c52015-10-09 02:32:53 -07003106TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003107 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003108 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003109 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003110 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003111 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003112 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3113 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3114 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003115}
3116
solenberg2100c0b2017-03-01 11:29:29 -08003117TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003118 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003119
3120 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003121 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003122 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3123
3124 // Should remember the volume "2" which will be set on new unsignaled streams,
3125 // and also set the gain to 2 on existing unsignaled streams.
3126 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3127 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3128
3129 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3130 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3131 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3132 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3133 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3134 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3135
3136 // Setting gain with SSRC=0 should affect all unsignaled streams.
3137 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003138 if (kMaxUnsignaledRecvStreams > 1) {
3139 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3140 }
solenberg2100c0b2017-03-01 11:29:29 -08003141 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3142
3143 // Setting gain on an individual stream affects only that.
3144 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003145 if (kMaxUnsignaledRecvStreams > 1) {
3146 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3147 }
solenberg2100c0b2017-03-01 11:29:29 -08003148 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003149}
3150
Seth Hampson845e8782018-03-02 11:34:10 -08003151TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003152 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003153 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003154
solenbergff976312016-03-30 23:28:51 -07003155 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003156 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003157 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003158 // Creating two channels to make sure that sync label is set properly for both
3159 // the default voice channel and following ones.
3160 EXPECT_TRUE(channel_->AddRecvStream(sp));
3161 sp.ssrcs[0] += 1;
3162 EXPECT_TRUE(channel_->AddRecvStream(sp));
3163
Mirko Bonadeif859e552018-05-30 15:31:29 +02003164 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003165 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003166 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003167 << "SyncGroup should be set based on stream id";
3168 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003169 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003170 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003171}
3172
solenberg3a941542015-11-16 07:34:50 -08003173// TODO(solenberg): Remove, once recv streams are configured through Call.
3174// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003175TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003176 // Test that setting the header extensions results in the expected state
3177 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003178 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003179 ssrcs.push_back(223);
3180 ssrcs.push_back(224);
3181
solenbergff976312016-03-30 23:28:51 -07003182 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003183 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003184 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003185 EXPECT_TRUE(
3186 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003187 }
3188
Mirko Bonadeif859e552018-05-30 15:31:29 +02003189 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003190 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003191 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003192 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003193 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003194 }
3195
3196 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003197 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003198 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003199 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003200 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003201 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003202 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003203 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003204 EXPECT_NE(nullptr, s);
3205 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003206 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3207 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003208 for (const auto& s_ext : s_exts) {
3209 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003210 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003211 }
3212 }
3213 }
3214 }
3215
3216 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003217 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003218 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003219 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003220 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003221 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003223}
3224
3225TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3226 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003227 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003228 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003230 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3231 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003233 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003234
solenbergff976312016-03-30 23:28:51 -07003235 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003236 cricket::WebRtcVoiceMediaChannel* media_channel =
3237 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003238 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003239 EXPECT_TRUE(media_channel->AddRecvStream(
3240 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3241
Mirko Bonadeif859e552018-05-30 15:31:29 +02003242 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003243 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003244 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003245 EXPECT_EQ(0, s->received_packets());
3246 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3247 EXPECT_EQ(1, s->received_packets());
3248 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3249 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003250}
Minyue2013aec2015-05-13 14:14:42 +02003251
solenberg0a617e22015-10-20 15:49:38 -07003252// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003253// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003254TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003255 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003256 EXPECT_TRUE(AddRecvStream(kSsrcY));
3257 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003258 EXPECT_TRUE(
3259 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003260 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3261 EXPECT_TRUE(AddRecvStream(kSsrcW));
3262 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003263}
3264
solenberg7602aab2016-11-14 11:30:07 -08003265TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3266 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003267 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003268 EXPECT_TRUE(
3269 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3271 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3272 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003273 EXPECT_TRUE(
3274 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3276 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003277}
stefan658910c2015-09-03 05:48:32 -07003278
deadbeef884f5852016-01-15 09:20:04 -08003279TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003280 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003281 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3282 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003283
3284 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003285 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3286 EXPECT_TRUE(AddRecvStream(kSsrcX));
3287 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003288
3289 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003290 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3291 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003292
3293 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003294 channel_->SetRawAudioSink(kSsrcX, nullptr);
3295 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003296}
3297
solenberg2100c0b2017-03-01 11:29:29 -08003298TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003299 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003300 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3301 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003302 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3303 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003304
3305 // Should be able to set a default sink even when no stream exists.
3306 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3307
solenberg2100c0b2017-03-01 11:29:29 -08003308 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3309 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003310 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003312
3313 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003314 channel_->SetRawAudioSink(kSsrc0, nullptr);
3315 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003316
3317 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003318 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3319 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003320
3321 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003322 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003323 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003324 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3325
3326 // Spawn another unsignaled stream - it should be assigned the default sink
3327 // and the previous unsignaled stream should lose it.
3328 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3329 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3330 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3331 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003332 if (kMaxUnsignaledRecvStreams > 1) {
3333 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3334 }
solenberg2100c0b2017-03-01 11:29:29 -08003335 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3336
3337 // Reset the default sink - the second unsignaled stream should lose it.
3338 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003339 if (kMaxUnsignaledRecvStreams > 1) {
3340 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3341 }
solenberg2100c0b2017-03-01 11:29:29 -08003342 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3343
3344 // Try setting the default sink while two streams exists.
3345 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003346 if (kMaxUnsignaledRecvStreams > 1) {
3347 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3348 }
solenberg2100c0b2017-03-01 11:29:29 -08003349 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3350
3351 // Try setting the sink for the first unsignaled stream using its known SSRC.
3352 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003353 if (kMaxUnsignaledRecvStreams > 1) {
3354 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3355 }
solenberg2100c0b2017-03-01 11:29:29 -08003356 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003357 if (kMaxUnsignaledRecvStreams > 1) {
3358 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3359 }
deadbeef884f5852016-01-15 09:20:04 -08003360}
3361
skvlad7a43d252016-03-22 15:32:27 -07003362// Test that, just like the video channel, the voice channel communicates the
3363// network state to the call.
3364TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003365 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003366
3367 EXPECT_EQ(webrtc::kNetworkUp,
3368 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3369 EXPECT_EQ(webrtc::kNetworkUp,
3370 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3371
3372 channel_->OnReadyToSend(false);
3373 EXPECT_EQ(webrtc::kNetworkDown,
3374 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3375 EXPECT_EQ(webrtc::kNetworkUp,
3376 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3377
3378 channel_->OnReadyToSend(true);
3379 EXPECT_EQ(webrtc::kNetworkUp,
3380 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3381 EXPECT_EQ(webrtc::kNetworkUp,
3382 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3383}
3384
aleloi18e0b672016-10-04 02:45:47 -07003385// Test that playout is still started after changing parameters
3386TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3387 SetupRecvStream();
3388 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003389 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003390
3391 // Changing RTP header extensions will recreate the AudioReceiveStream.
3392 cricket::AudioRecvParameters parameters;
3393 parameters.extensions.push_back(
3394 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3395 channel_->SetRecvParameters(parameters);
3396
solenberg2100c0b2017-03-01 11:29:29 -08003397 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003398}
3399
Zhi Huangfa266ef2017-12-13 10:27:46 -08003400// Tests when GetSources is called with non-existing ssrc, it will return an
3401// empty list of RtpSource without crashing.
3402TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3403 // Setup an recv stream with |kSsrcX|.
3404 SetupRecvStream();
3405 cricket::WebRtcVoiceMediaChannel* media_channel =
3406 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3407 // Call GetSources with |kSsrcY| which doesn't exist.
3408 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3409 EXPECT_EQ(0u, sources.size());
3410}
3411
stefan658910c2015-09-03 05:48:32 -07003412// Tests that the library initializes and shuts down properly.
3413TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003414 // If the VoiceEngine wants to gather available codecs early, that's fine but
3415 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003416 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003417 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003418 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003419 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003420 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003421 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003422 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003423 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003424 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003425 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003426 cricket::VoiceMediaChannel* channel =
3427 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3428 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003429 EXPECT_TRUE(channel != nullptr);
3430 delete channel;
solenbergff976312016-03-30 23:28:51 -07003431}
stefan658910c2015-09-03 05:48:32 -07003432
solenbergff976312016-03-30 23:28:51 -07003433// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003434TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3435 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003436 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003437 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003438 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003439 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003440 {
peaha9cc40b2017-06-29 08:32:09 -07003441 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003442 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003443 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003444 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003445 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003446 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003447 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003448 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003449 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003450 cricket::VoiceMediaChannel* channel =
3451 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3452 cricket::AudioOptions(), webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003453 EXPECT_TRUE(channel != nullptr);
3454 delete channel;
3455 }
stefan658910c2015-09-03 05:48:32 -07003456}
3457
ossu20a4b3f2017-04-27 02:08:52 -07003458// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3459TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003460 // TODO(ossu): Why are the payload types of codecs with non-static payload
3461 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003462 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003463 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003464 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003465 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003466 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003467 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003468 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003469 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003470 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003471 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003472 (clockrate == 0 || codec.clockrate == clockrate);
3473 };
3474 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003475 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003476 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003477 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003478 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003479 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003480 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003481 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003482 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003483 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003484 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003485 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003486 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3487 // Remove these checks once both send and receive side assigns payload
3488 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003489 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003490 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003491 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003492 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003493 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003494 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003495 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003496 EXPECT_EQ(111, codec.id);
3497 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3498 EXPECT_EQ("10", codec.params.find("minptime")->second);
3499 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3500 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003501 }
3502 }
stefan658910c2015-09-03 05:48:32 -07003503}
3504
3505// Tests that VoE supports at least 32 channels
3506TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003507 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003508 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003509 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003510 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003511 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003512 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003513 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003514 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003515 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003516 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003517
3518 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003519 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003520 while (num_channels < arraysize(channels)) {
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003521 cricket::VoiceMediaChannel* channel =
3522 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3523 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003524 if (!channel)
3525 break;
stefan658910c2015-09-03 05:48:32 -07003526 channels[num_channels++] = channel;
3527 }
3528
Mirko Bonadeif859e552018-05-30 15:31:29 +02003529 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003530 EXPECT_EQ(expected, num_channels);
3531
3532 while (num_channels > 0) {
3533 delete channels[--num_channels];
3534 }
stefan658910c2015-09-03 05:48:32 -07003535}
3536
3537// Test that we set our preferred codecs properly.
3538TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003539 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3540 // - Check that our builtin codecs are usable by Channel.
3541 // - The codecs provided by the engine is usable by Channel.
3542 // It does not check that the codecs in the RecvParameters are actually
3543 // what we sent in - though it's probably reasonable to expect so, if
3544 // SetRecvParameters returns true.
3545 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003546 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003547 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003548 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003549 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003550 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003551 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003552 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003553 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003554 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003555 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003556 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003557 cricket::AudioOptions(),
3558 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003559 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003560 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003561 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003562}
ossu9def8002017-02-09 05:14:32 -08003563
3564TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3565 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003566 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3567 {48000, 2, 16000, 10000, 20000}};
3568 spec1.info.allow_comfort_noise = false;
3569 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003570 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003571 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3572 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003573 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003574 specs.push_back(webrtc::AudioCodecSpec{
3575 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3576 {16000, 1, 13300}});
3577 specs.push_back(
3578 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3579 specs.push_back(
3580 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003581
ossueb1fde42017-05-02 06:46:30 -07003582 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3583 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3584 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003585 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003586 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003587 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003588 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003589
peaha9cc40b2017-06-29 08:32:09 -07003590 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003591 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003592 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003593 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003594 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003595 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003596 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003597
3598 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3599 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003600 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3601 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3602 if (codecs.size() > index)
3603 return codecs[index];
3604 return missing_codec;
3605 };
ossu9def8002017-02-09 05:14:32 -08003606
3607 // Ensure the general codecs are generated first and in order.
3608 for (size_t i = 0; i != specs.size(); ++i) {
3609 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3610 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3611 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3612 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3613 }
3614
3615 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003616 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003617 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3618 for (size_t i = 0; i != codecs.size(); ++i) {
3619 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003620 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003621 codec.clockrate == format.clockrate_hz &&
3622 codec.channels == format.num_channels) {
3623 return rtc::checked_cast<int>(i);
3624 }
3625 }
3626 return -1;
3627 };
ossu9def8002017-02-09 05:14:32 -08003628
3629 // Ensure all supplementary codecs are generated last. Their internal ordering
3630 // is not important.
3631 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3632 const int num_specs = static_cast<int>(specs.size());
3633 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3634 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3635 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3636 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3637 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3638 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3639 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3640}