blob: 4b1a5287b6511af056a1fe1ec1a3f1cf83c69426 [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"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "call/call.h"
20#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/base/fake_media_engine.h"
22#include "media/base/fake_network_interface.h"
23#include "media/base/fake_rtp.h"
24#include "media/base/media_constants.h"
25#include "media/engine/fake_webrtc_call.h"
26#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_device/include/mock_audio_device.h"
28#include "modules/audio_processing/include/mock_audio_processing.h"
29#include "pc/channel.h"
30#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010032#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#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
Elad Alon157540a2019-02-08 23:37:52 +010038using ::testing::_;
39using ::testing::ContainerEq;
40using ::testing::Contains;
41using ::testing::Field;
42using ::testing::Return;
43using ::testing::ReturnPointee;
44using ::testing::SaveArg;
45using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000046
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020047namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010048using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020049
solenberg418b7d32017-06-13 00:38:27 -070050constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070051
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
53const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070054const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
56const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070057const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
58const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020059const cricket::AudioCodec kTelephoneEventCodec1(106,
60 "telephone-event",
61 8000,
62 0,
63 1);
64const cricket::AudioCodec kTelephoneEventCodec2(107,
65 "telephone-event",
66 32000,
67 0,
68 1);
solenberg2779bab2016-11-17 04:45:19 -080069
solenberg2100c0b2017-03-01 11:29:29 -080070const uint32_t kSsrc0 = 0;
71const uint32_t kSsrc1 = 1;
72const uint32_t kSsrcX = 0x99;
73const uint32_t kSsrcY = 0x17;
74const uint32_t kSsrcZ = 0x42;
75const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020076const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077
solenberg971cab02016-06-14 10:02:41 -070078constexpr int kRtpHistoryMs = 5000;
79
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010080constexpr webrtc::GainControl::Mode kDefaultAgcMode =
81#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
82 webrtc::GainControl::kFixedDigital;
83#else
84 webrtc::GainControl::kAdaptiveAnalog;
85#endif
86
87constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
88 webrtc::NoiseSuppression::kHigh;
89
solenberg9a5f032222017-03-15 06:14:12 -070090void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
91 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010092
93 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010094 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010095 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010096 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070097#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020098 EXPECT_CALL(
99 *adm, SetPlayoutDevice(
100 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
101 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
102 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700103#else
104 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
105#endif // #if defined(WEBRTC_WIN)
106 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
107 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
108 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100109#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200110 EXPECT_CALL(
111 *adm, SetRecordingDevice(
112 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
113 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
114 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100115#else
116 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
117#endif // #if defined(WEBRTC_WIN)
118 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
119 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
120 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700121 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
122 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
123 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100124
125 // Teardown.
126 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
127 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
128 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
129 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200130 EXPECT_CALL(*adm, Release())
131 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100132 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700133}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200134} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135
solenbergff976312016-03-30 23:28:51 -0700136// Tests that our stub library "works".
137TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700138 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700139 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700140 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
141 new rtc::RefCountedObject<
142 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700143 webrtc::AudioProcessing::Config apm_config;
144 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
145 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700146 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700147 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700148 {
ossuc54071d2016-08-17 02:45:41 -0700149 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700150 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100151 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700152 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700153 }
solenbergff976312016-03-30 23:28:51 -0700154}
155
deadbeef884f5852016-01-15 09:20:04 -0800156class FakeAudioSink : public webrtc::AudioSinkInterface {
157 public:
158 void OnData(const Data& audio) override {}
159};
160
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800161class FakeAudioSource : public cricket::AudioSource {
162 void SetSink(Sink* sink) override {}
163};
164
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165class WebRtcVoiceEngineTestFake : public testing::Test {
166 public:
stefanba4c0e42016-02-04 04:12:24 -0800167 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
168
169 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700170 : apm_(new rtc::RefCountedObject<
171 StrictMock<webrtc::test::MockAudioProcessing>>()),
172 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700173 apm_ns_(*apm_->noise_suppression()),
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));
solenberg76377c52017-02-21 00:54:31 -0800189 // Init does not overwrite default AGC config.
190 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
191 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
192 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
194 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700195 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800196 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700197 // factories. Those tests should probably be moved elsewhere.
198 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
199 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100200 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100201 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200207 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100209 EXPECT_TRUE(IsTypingDetectionEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700213 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100214 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
215 cricket::AudioOptions(),
216 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200217 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000218 }
solenberg8189b022016-06-14 12:13:00 -0700219
solenbergff976312016-03-30 23:28:51 -0700220 bool SetupRecvStream() {
221 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700222 return false;
223 }
solenberg2100c0b2017-03-01 11:29:29 -0800224 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700225 }
solenberg8189b022016-06-14 12:13:00 -0700226
solenbergff976312016-03-30 23:28:51 -0700227 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200228 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
229 }
230
231 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700232 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000233 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
Florent Castellidacec712018-05-24 16:24:21 +0200235 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800236 return false;
237 }
peaha9cc40b2017-06-29 08:32:09 -0700238 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800239 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
242 bool AddRecvStream(uint32_t ssrc) {
243 EXPECT_TRUE(channel_);
244 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
245 }
246
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700248 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700249 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800250 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
251 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700252 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800253 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700257 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Niels Möllere6933812018-11-05 13:01:41 +0100258 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 }
solenberg8189b022016-06-14 12:13:00 -0700260
Yves Gerey665174f2018-06-19 15:03:05 +0200261 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100263 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
264 const auto* send_stream = call_.GetAudioSendStream(ssrc);
265 EXPECT_TRUE(send_stream);
266 return *send_stream;
267 }
268
deadbeef884f5852016-01-15 09:20:04 -0800269 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
270 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
271 EXPECT_TRUE(recv_stream);
272 return *recv_stream;
273 }
274
solenberg3a941542015-11-16 07:34:50 -0800275 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800276 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800277 }
278
solenberg7add0582015-11-20 09:59:34 -0800279 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800280 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800281 }
282
solenberg059fb442016-10-26 05:12:24 -0700283 void SetSend(bool enable) {
284 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700285 if (enable) {
286 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
288 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700289 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700290 }
solenberg059fb442016-10-26 05:12:24 -0700291 channel_->SetSend(enable);
292 }
293
294 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700295 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700296 ASSERT_TRUE(channel_);
297 EXPECT_TRUE(channel_->SetSendParameters(params));
298 }
299
Yves Gerey665174f2018-06-19 15:03:05 +0200300 void SetAudioSend(uint32_t ssrc,
301 bool enable,
302 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700303 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700304 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700305 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700306 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700307 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700308 }
309 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700310 }
311
Yves Gerey665174f2018-06-19 15:03:05 +0200312 void TestInsertDtmf(uint32_t ssrc,
313 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800314 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700315 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700317 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200319 EXPECT_TRUE(
320 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700324 SetSendParameters(send_parameters_);
325 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800327 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800328 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700329 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331
332 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700333 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800334 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200335 EXPECT_TRUE(
336 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000337 }
338
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800340 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100342 // Test send.
343 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800344 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100345 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800346 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800347 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800348 EXPECT_EQ(codec.id, telephone_event.payload_type);
349 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100350 EXPECT_EQ(2, telephone_event.event_code);
351 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
353
Johannes Kron9190b822018-10-29 11:22:05 +0100354 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
355 // For a caller, the answer will be applied in set remote description
356 // where SetSendParameters() is called.
357 EXPECT_TRUE(SetupChannel());
358 EXPECT_TRUE(
359 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
360 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
361 SetSendParameters(send_parameters_);
362 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
363 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
364 }
365
366 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
367 // For a callee, the answer will be applied in set local description
368 // where SetExtmapAllowMixed() and AddSendStream() are called.
369 EXPECT_TRUE(SetupChannel());
370 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
371 EXPECT_TRUE(
372 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
373
374 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
375 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
376 }
377
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 // Test that send bandwidth is set correctly.
379 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000380 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
381 // |expected_result| is the expected result from SetMaxSendBandwidth().
382 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700383 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
384 int max_bitrate,
385 bool expected_result,
386 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200387 cricket::AudioSendParameters parameters;
388 parameters.codecs.push_back(codec);
389 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700390 if (expected_result) {
391 SetSendParameters(parameters);
392 } else {
393 EXPECT_FALSE(channel_->SetSendParameters(parameters));
394 }
solenberg2100c0b2017-03-01 11:29:29 -0800395 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000396 }
397
skvlade0d46372016-04-07 22:59:22 -0700398 // Sets the per-stream maximum bitrate limit for the specified SSRC.
399 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700400 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700401 EXPECT_EQ(1UL, parameters.encodings.size());
402
Oskar Sundbom78807582017-11-16 11:09:55 +0100403 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800404 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700405 }
406
solenberg059fb442016-10-26 05:12:24 -0700407 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700408 cricket::AudioSendParameters send_parameters;
409 send_parameters.codecs.push_back(codec);
410 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700411 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700412 }
413
ossu20a4b3f2017-04-27 02:08:52 -0700414 void CheckSendCodecBitrate(int32_t ssrc,
415 const char expected_name[],
416 int expected_bitrate) {
417 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
418 EXPECT_EQ(expected_name, spec->format.name);
419 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700420 }
421
Danil Chapovalov00c71832018-06-15 15:58:38 +0200422 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700423 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700424 }
425
Danil Chapovalov00c71832018-06-15 15:58:38 +0200426 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
427 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700428 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
429 }
430
skvlade0d46372016-04-07 22:59:22 -0700431 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
432 int global_max,
433 int stream_max,
434 bool expected_result,
435 int expected_codec_bitrate) {
436 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800437 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700438
439 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700440 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800441 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700442
443 // Verify that reading back the parameters gives results
444 // consistent with the Set() result.
445 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800446 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700447 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
448 EXPECT_EQ(expected_result ? stream_max : -1,
449 resulting_parameters.encodings[0].max_bitrate_bps);
450
451 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800452 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700453 }
454
stefan13f1a0a2016-11-30 07:22:58 -0800455 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
456 int expected_min_bitrate_bps,
457 const char* start_bitrate_kbps,
458 int expected_start_bitrate_bps,
459 const char* max_bitrate_kbps,
460 int expected_max_bitrate_bps) {
461 EXPECT_TRUE(SetupSendStream());
462 auto& codecs = send_parameters_.codecs;
463 codecs.clear();
464 codecs.push_back(kOpusCodec);
465 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
466 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
467 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100468 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
469 SetSdpBitrateParameters(
470 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
471 expected_min_bitrate_bps),
472 Field(&BitrateConstraints::start_bitrate_bps,
473 expected_start_bitrate_bps),
474 Field(&BitrateConstraints::max_bitrate_bps,
475 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800476
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100477 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800478 }
479
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000480 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700481 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000482
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000483 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000485
486 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700487 send_parameters_.extensions.push_back(
488 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700489 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200493 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700494 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000496
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000497 // Ensure extension is set properly.
498 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700499 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700500 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
502 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
503 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000504
solenberg7add0582015-11-20 09:59:34 -0800505 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200506 EXPECT_TRUE(
507 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800508 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
509 call_.GetAudioSendStream(kSsrcY));
510 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
511 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
514 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200515 send_parameters_.codecs.push_back(kPcmuCodec);
516 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700517 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800518 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
519 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000520 }
521
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000522 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700523 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000525 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000527
528 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700529 recv_parameters_.extensions.push_back(
530 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800531 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800532 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000533
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000534 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800535 recv_parameters_.extensions.clear();
536 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800537 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000538
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000539 // Ensure extension is set properly.
540 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700541 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800542 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800543 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
544 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
545 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000546
solenberg7add0582015-11-20 09:59:34 -0800547 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800548 EXPECT_TRUE(AddRecvStream(kSsrcY));
549 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
550 call_.GetAudioReceiveStream(kSsrcY));
551 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
552 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
553 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000554
555 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800556 recv_parameters_.extensions.clear();
557 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800558 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
559 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000560 }
561
solenberg85a04962015-10-27 03:35:21 -0700562 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
563 webrtc::AudioSendStream::Stats stats;
564 stats.local_ssrc = 12;
565 stats.bytes_sent = 345;
566 stats.packets_sent = 678;
567 stats.packets_lost = 9012;
568 stats.fraction_lost = 34.56f;
569 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100570 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700571 stats.ext_seqnum = 789;
572 stats.jitter_ms = 12;
573 stats.rtt_ms = 345;
574 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100575 stats.apm_statistics.delay_median_ms = 234;
576 stats.apm_statistics.delay_standard_deviation_ms = 567;
577 stats.apm_statistics.echo_return_loss = 890;
578 stats.apm_statistics.echo_return_loss_enhancement = 1234;
579 stats.apm_statistics.residual_echo_likelihood = 0.432f;
580 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100581 stats.ana_statistics.bitrate_action_counter = 321;
582 stats.ana_statistics.channel_action_counter = 432;
583 stats.ana_statistics.dtx_action_counter = 543;
584 stats.ana_statistics.fec_action_counter = 654;
585 stats.ana_statistics.frame_length_increase_counter = 765;
586 stats.ana_statistics.frame_length_decrease_counter = 876;
587 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700588 stats.typing_noise_detected = true;
589 return stats;
590 }
591 void SetAudioSendStreamStats() {
592 for (auto* s : call_.GetAudioSendStreams()) {
593 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200594 }
solenberg85a04962015-10-27 03:35:21 -0700595 }
solenberg566ef242015-11-06 15:34:49 -0800596 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
597 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700598 const auto stats = GetAudioSendStreamStats();
599 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
600 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
601 EXPECT_EQ(info.packets_sent, stats.packets_sent);
602 EXPECT_EQ(info.packets_lost, stats.packets_lost);
603 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
604 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800605 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700606 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
607 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
608 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
609 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100610 EXPECT_EQ(info.apm_statistics.delay_median_ms,
611 stats.apm_statistics.delay_median_ms);
612 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
613 stats.apm_statistics.delay_standard_deviation_ms);
614 EXPECT_EQ(info.apm_statistics.echo_return_loss,
615 stats.apm_statistics.echo_return_loss);
616 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
617 stats.apm_statistics.echo_return_loss_enhancement);
618 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
619 stats.apm_statistics.residual_echo_likelihood);
620 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
621 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700622 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
623 stats.ana_statistics.bitrate_action_counter);
624 EXPECT_EQ(info.ana_statistics.channel_action_counter,
625 stats.ana_statistics.channel_action_counter);
626 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
627 stats.ana_statistics.dtx_action_counter);
628 EXPECT_EQ(info.ana_statistics.fec_action_counter,
629 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700630 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
631 stats.ana_statistics.frame_length_increase_counter);
632 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
633 stats.ana_statistics.frame_length_decrease_counter);
634 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
635 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800636 EXPECT_EQ(info.typing_noise_detected,
637 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700638 }
639
640 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
641 webrtc::AudioReceiveStream::Stats stats;
642 stats.remote_ssrc = 123;
643 stats.bytes_rcvd = 456;
644 stats.packets_rcvd = 768;
645 stats.packets_lost = 101;
646 stats.fraction_lost = 23.45f;
647 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100648 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700649 stats.ext_seqnum = 678;
650 stats.jitter_ms = 901;
651 stats.jitter_buffer_ms = 234;
652 stats.jitter_buffer_preferred_ms = 567;
653 stats.delay_estimate_ms = 890;
654 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700655 stats.total_samples_received = 5678901;
656 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200657 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200658 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100659 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700660 stats.expand_rate = 5.67f;
661 stats.speech_expand_rate = 8.90f;
662 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200663 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700664 stats.accelerate_rate = 4.56f;
665 stats.preemptive_expand_rate = 7.89f;
666 stats.decoding_calls_to_silence_generator = 12;
667 stats.decoding_calls_to_neteq = 345;
668 stats.decoding_normal = 67890;
669 stats.decoding_plc = 1234;
670 stats.decoding_cng = 5678;
671 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700672 stats.decoding_muted_output = 3456;
673 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200674 return stats;
675 }
676 void SetAudioReceiveStreamStats() {
677 for (auto* s : call_.GetAudioReceiveStreams()) {
678 s->SetStats(GetAudioReceiveStreamStats());
679 }
680 }
681 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700682 const auto stats = GetAudioReceiveStreamStats();
683 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
684 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200685 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
686 stats.packets_rcvd);
687 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
688 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700689 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
690 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800691 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
693 stats.ext_seqnum);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
696 stats.jitter_buffer_ms);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700698 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
700 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700701 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700702 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
703 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200704 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200705 EXPECT_EQ(info.jitter_buffer_delay_seconds,
706 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100707 EXPECT_EQ(info.jitter_buffer_emitted_count,
708 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700709 EXPECT_EQ(info.expand_rate, stats.expand_rate);
710 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
711 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200712 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700713 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
714 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200715 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700716 stats.decoding_calls_to_silence_generator);
717 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
718 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
719 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
720 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
721 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700722 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700723 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200724 }
hbos1acfbd22016-11-17 23:43:29 -0800725 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
726 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
727 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
728 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
729 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
730 codec.ToCodecParameters());
731 }
732 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
733 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
734 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
735 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
736 codec.ToCodecParameters());
737 }
738 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200739
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200740 bool IsEchoCancellationEnabled() {
741 return engine_->GetApmConfigForTest().echo_canceller.enabled;
742 }
743
peah8271d042016-11-22 07:24:52 -0800744 bool IsHighPassFilterEnabled() {
745 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
746 }
747
Sam Zackrissonba502232019-01-04 10:36:48 +0100748 bool IsTypingDetectionEnabled() {
749 return engine_->GetApmConfigForTest().voice_detection.enabled;
750 }
751
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000752 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700753 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700754 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800755 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800756 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200757 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700758 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700759 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200760 cricket::AudioSendParameters send_parameters_;
761 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800762 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700763 webrtc::AudioProcessing::Config apm_config_;
764
stefanba4c0e42016-02-04 04:12:24 -0800765 private:
766 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767};
768
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100770TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700771 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772}
773
solenberg31fec402016-05-06 02:13:12 -0700774// Test that we can add a send stream and that it has the correct defaults.
775TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
776 EXPECT_TRUE(SetupChannel());
777 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800778 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
779 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
780 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700781 EXPECT_EQ("", config.rtp.c_name);
782 EXPECT_EQ(0u, config.rtp.extensions.size());
783 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
784 config.send_transport);
785}
786
787// Test that we can add a receive stream and that it has the correct defaults.
788TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
789 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800790 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700791 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800792 GetRecvStreamConfig(kSsrcX);
793 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700794 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
795 EXPECT_FALSE(config.rtp.transport_cc);
796 EXPECT_EQ(0u, config.rtp.extensions.size());
797 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
798 config.rtcp_send_transport);
799 EXPECT_EQ("", config.sync_group);
800}
801
stefanba4c0e42016-02-04 04:12:24 -0800802TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700803 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800804 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100805 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800806 if (codec.name == "opus") {
807 EXPECT_TRUE(HasTransportCc(codec));
808 opus_found = true;
809 }
810 }
811 EXPECT_TRUE(opus_found);
812}
813
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814// Test that we set our inbound codecs properly, including changing PT.
815TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700816 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200817 cricket::AudioRecvParameters parameters;
818 parameters.codecs.push_back(kIsacCodec);
819 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800820 parameters.codecs.push_back(kTelephoneEventCodec1);
821 parameters.codecs.push_back(kTelephoneEventCodec2);
822 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200823 parameters.codecs[2].id = 126;
824 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800825 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700826 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
827 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
828 {{0, {"PCMU", 8000, 1}},
829 {106, {"ISAC", 16000, 1}},
830 {126, {"telephone-event", 8000, 1}},
831 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832}
833
834// Test that we fail to set an unknown inbound codec.
835TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700836 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200837 cricket::AudioRecvParameters parameters;
838 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700839 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we fail if we have duplicate types in the inbound list.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kCn16000Codec);
849 parameters.codecs[1].id = kIsacCodec.id;
850 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851}
852
853// Test that we can decode OPUS without stereo parameters.
854TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700855 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 cricket::AudioRecvParameters parameters;
857 parameters.codecs.push_back(kIsacCodec);
858 parameters.codecs.push_back(kPcmuCodec);
859 parameters.codecs.push_back(kOpusCodec);
860 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800861 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700862 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
863 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
864 {{0, {"PCMU", 8000, 1}},
865 {103, {"ISAC", 16000, 1}},
866 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867}
868
869// Test that we can decode OPUS with stereo = 0.
870TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700871 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200872 cricket::AudioRecvParameters parameters;
873 parameters.codecs.push_back(kIsacCodec);
874 parameters.codecs.push_back(kPcmuCodec);
875 parameters.codecs.push_back(kOpusCodec);
876 parameters.codecs[2].params["stereo"] = "0";
877 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800878 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700879 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
880 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
881 {{0, {"PCMU", 8000, 1}},
882 {103, {"ISAC", 16000, 1}},
883 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884}
885
886// Test that we can decode OPUS with stereo = 1.
887TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700888 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 cricket::AudioRecvParameters parameters;
890 parameters.codecs.push_back(kIsacCodec);
891 parameters.codecs.push_back(kPcmuCodec);
892 parameters.codecs.push_back(kOpusCodec);
893 parameters.codecs[2].params["stereo"] = "1";
894 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800895 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700896 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
897 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
898 {{0, {"PCMU", 8000, 1}},
899 {103, {"ISAC", 16000, 1}},
900 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
903// Test that changes to recv codecs are applied to all streams.
904TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700905 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200906 cricket::AudioRecvParameters parameters;
907 parameters.codecs.push_back(kIsacCodec);
908 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800909 parameters.codecs.push_back(kTelephoneEventCodec1);
910 parameters.codecs.push_back(kTelephoneEventCodec2);
911 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 parameters.codecs[2].id = 126;
913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700914 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
915 EXPECT_TRUE(AddRecvStream(ssrc));
916 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
917 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
918 {{0, {"PCMU", 8000, 1}},
919 {106, {"ISAC", 16000, 1}},
920 {126, {"telephone-event", 8000, 1}},
921 {107, {"telephone-event", 32000, 1}}})));
922 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
925TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
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);
solenberg2779bab2016-11-17 04:45:19 -0800929 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931
solenberg2100c0b2017-03-01 11:29:29 -0800932 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200933 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800934 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935}
936
937// Test that we can apply the same set of codecs again while playing.
938TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200940 cricket::AudioRecvParameters parameters;
941 parameters.codecs.push_back(kIsacCodec);
942 parameters.codecs.push_back(kCn16000Codec);
943 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700944 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
deadbeefcb383672017-04-26 16:28:42 -0700947 // Remapping a payload type to a different codec should fail.
948 parameters.codecs[0] = kOpusCodec;
949 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200950 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800951 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
954// Test that we can add a codec while playing.
955TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 cricket::AudioRecvParameters parameters;
958 parameters.codecs.push_back(kIsacCodec);
959 parameters.codecs.push_back(kCn16000Codec);
960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700961 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200963 parameters.codecs.push_back(kOpusCodec);
964 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800965 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966}
967
deadbeefcb383672017-04-26 16:28:42 -0700968// Test that we accept adding the same codec with a different payload type.
969// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
970TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
971 EXPECT_TRUE(SetupRecvStream());
972 cricket::AudioRecvParameters parameters;
973 parameters.codecs.push_back(kIsacCodec);
974 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
975
976 ++parameters.codecs[0].id;
977 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
978}
979
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983 // Test that when autobw is enabled, bitrate is kept as the default
984 // value. autobw is enabled for the following tests because the target
985 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986
987 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700988 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989
990 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700991 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992
ossu20a4b3f2017-04-27 02:08:52 -0700993 // opus, default bitrate == 32000 in mono.
994 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995}
996
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000997TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001001 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1002 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001003 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1007 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1008 // Rates above the max (510000) should be capped.
1009 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010}
1011
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001013 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001014
1015 // Test that we can only set a maximum bitrate for a fixed-rate codec
1016 // if it's bigger than the fixed rate.
1017
1018 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001019 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1020 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1021 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1022 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1023 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1024 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1025 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001026}
1027
1028TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001029 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001030 const int kDesiredBitrate = 128000;
1031 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001032 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001033 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001034 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001035
Yves Gerey665174f2018-06-19 15:03:05 +02001036 EXPECT_TRUE(
1037 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001038
solenberg2100c0b2017-03-01 11:29:29 -08001039 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001040}
1041
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001042// Test that bitrate cannot be set for CBR codecs.
1043// Bitrate is ignored if it is higher than the fixed bitrate.
1044// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001045TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001046 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001047
1048 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001049 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001050 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001051
1052 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001053 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001055
1056 send_parameters_.max_bandwidth_bps = 128;
1057 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001058 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059}
1060
skvlade0d46372016-04-07 22:59:22 -07001061// Test that the per-stream bitrate limit and the global
1062// bitrate limit both apply.
1063TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1064 EXPECT_TRUE(SetupSendStream());
1065
ossu20a4b3f2017-04-27 02:08:52 -07001066 // opus, default bitrate == 32000.
1067 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001068 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1069 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1070 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1071
1072 // CBR codecs allow both maximums to exceed the bitrate.
1073 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1074 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1075 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1076 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1077
1078 // CBR codecs don't allow per stream maximums to be too low.
1079 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1080 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1081}
1082
1083// Test that an attempt to set RtpParameters for a stream that does not exist
1084// fails.
1085TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1086 EXPECT_TRUE(SetupChannel());
1087 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001088 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001089 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001090
1091 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001092 EXPECT_FALSE(
1093 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001094}
1095
1096TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001098 // This test verifies that setting RtpParameters succeeds only if
1099 // the structure contains exactly one encoding.
1100 // TODO(skvlad): Update this test when we start supporting setting parameters
1101 // for each encoding individually.
1102
1103 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001104 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001105 // Two or more encodings should result in failure.
1106 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001108 // Zero encodings should also fail.
1109 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001110 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001111}
1112
1113// Changing the SSRC through RtpParameters is not allowed.
1114TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1115 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001116 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001117 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001118 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001119}
1120
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001121// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001122// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001123TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1124 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001125 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001126 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001127 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001128 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001129 ASSERT_EQ(1u, parameters.encodings.size());
1130 ASSERT_TRUE(parameters.encodings[0].active);
1131 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001132 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001133 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001134
1135 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001136 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001137 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001138 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001139 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001140 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001141}
1142
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001143// Test that SetRtpSendParameters configures the correct encoding channel for
1144// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001145TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1146 SetupForMultiSendStream();
1147 // Create send streams.
1148 for (uint32_t ssrc : kSsrcs4) {
1149 EXPECT_TRUE(
1150 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1151 }
1152 // Configure one stream to be limited by the stream config, another to be
1153 // limited by the global max, and the third one with no per-stream limit
1154 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001155 SetGlobalMaxBitrate(kOpusCodec, 32000);
1156 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1157 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001158 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1159
ossu20a4b3f2017-04-27 02:08:52 -07001160 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1161 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1162 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001163
1164 // Remove the global cap; the streams should switch to their respective
1165 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001166 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001167 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1168 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1169 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001170}
1171
Tim Haloun648d28a2018-10-18 16:52:22 -07001172// RTCRtpEncodingParameters.network_priority must be one of a few values
1173// derived from the default priority, corresponding to very-low, low, medium,
1174// or high.
1175TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1176 EXPECT_TRUE(SetupSendStream());
1177 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1178 EXPECT_EQ(1UL, parameters.encodings.size());
1179 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1180 parameters.encodings[0].network_priority);
1181
1182 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1183 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1184 for (auto it : good_values) {
1185 parameters.encodings[0].network_priority = it;
1186 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1187 }
1188 for (auto it : bad_values) {
1189 parameters.encodings[0].network_priority = it;
1190 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1191 }
1192}
1193
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001194// Test that GetRtpSendParameters returns the currently configured codecs.
1195TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001196 EXPECT_TRUE(SetupSendStream());
1197 cricket::AudioSendParameters parameters;
1198 parameters.codecs.push_back(kIsacCodec);
1199 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001200 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001201
solenberg2100c0b2017-03-01 11:29:29 -08001202 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001203 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001204 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1205 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001206}
1207
Florent Castellidacec712018-05-24 16:24:21 +02001208// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1209TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1210 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1211 params.cname = "rtcpcname";
1212 EXPECT_TRUE(SetupSendStream(params));
1213
1214 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1215 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1216}
1217
Florent Castelliabe301f2018-06-12 18:33:49 +02001218TEST_F(WebRtcVoiceEngineTestFake,
1219 DetectRtpSendParameterHeaderExtensionsChange) {
1220 EXPECT_TRUE(SetupSendStream());
1221
1222 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1223 rtp_parameters.header_extensions.emplace_back();
1224
1225 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1226
1227 webrtc::RTCError result =
1228 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1229 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1230}
1231
deadbeefcb443432016-12-12 11:12:36 -08001232// Test that GetRtpSendParameters returns an SSRC.
1233TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1234 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001235 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001236 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001237 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001238}
1239
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001240// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001241TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001242 EXPECT_TRUE(SetupSendStream());
1243 cricket::AudioSendParameters parameters;
1244 parameters.codecs.push_back(kIsacCodec);
1245 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001246 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001247
solenberg2100c0b2017-03-01 11:29:29 -08001248 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001249
1250 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001251 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001252
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001253 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001254 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1255 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001256}
1257
minyuececec102017-03-27 13:04:25 -07001258// Test that max_bitrate_bps in send stream config gets updated correctly when
1259// SetRtpSendParameters is called.
1260TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1261 webrtc::test::ScopedFieldTrials override_field_trials(
1262 "WebRTC-Audio-SendSideBwe/Enabled/");
1263 EXPECT_TRUE(SetupSendStream());
1264 cricket::AudioSendParameters send_parameters;
1265 send_parameters.codecs.push_back(kOpusCodec);
1266 SetSendParameters(send_parameters);
1267
1268 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1269 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1270 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1271
1272 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001273 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001274 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001275
1276 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1277 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1278}
1279
Seth Hampson24722b32017-12-22 09:36:42 -08001280// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1281// a value <= 0, setting the parameters returns false.
1282TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1283 EXPECT_TRUE(SetupSendStream());
1284 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1285 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1286 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1287 rtp_parameters.encodings[0].bitrate_priority);
1288
1289 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001290 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001291 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001292 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001293}
1294
1295// Test that the bitrate_priority in the send stream config gets updated when
1296// SetRtpSendParameters is set for the VoiceMediaChannel.
1297TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1298 EXPECT_TRUE(SetupSendStream());
1299 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1300
1301 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1302 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1303 rtp_parameters.encodings[0].bitrate_priority);
1304 double new_bitrate_priority = 2.0;
1305 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001306 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001307
1308 // The priority should get set for both the audio channel's rtp parameters
1309 // and the audio send stream's audio config.
1310 EXPECT_EQ(
1311 new_bitrate_priority,
1312 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1313 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1314}
1315
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001316// Test that GetRtpReceiveParameters returns the currently configured codecs.
1317TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1318 EXPECT_TRUE(SetupRecvStream());
1319 cricket::AudioRecvParameters parameters;
1320 parameters.codecs.push_back(kIsacCodec);
1321 parameters.codecs.push_back(kPcmuCodec);
1322 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1323
1324 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001325 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001326 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1327 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1328 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1329}
1330
deadbeefcb443432016-12-12 11:12:36 -08001331// Test that GetRtpReceiveParameters returns an SSRC.
1332TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1333 EXPECT_TRUE(SetupRecvStream());
1334 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001335 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001336 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001337 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001338}
1339
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001340// Test that if we set/get parameters multiple times, we get the same results.
1341TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1342 EXPECT_TRUE(SetupRecvStream());
1343 cricket::AudioRecvParameters parameters;
1344 parameters.codecs.push_back(kIsacCodec);
1345 parameters.codecs.push_back(kPcmuCodec);
1346 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1347
1348 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001349 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001350
1351 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001352 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001353
1354 // ... And this shouldn't change the params returned by
1355 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001356 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1357 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001358}
1359
deadbeef3bc15102017-04-20 19:25:07 -07001360// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1361// aren't signaled. It should return an empty "RtpEncodingParameters" when
1362// configured to receive an unsignaled stream and no packets have been received
1363// yet, and start returning the SSRC once a packet has been received.
1364TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1365 ASSERT_TRUE(SetupChannel());
1366 // Call necessary methods to configure receiving a default stream as
1367 // soon as it arrives.
1368 cricket::AudioRecvParameters parameters;
1369 parameters.codecs.push_back(kIsacCodec);
1370 parameters.codecs.push_back(kPcmuCodec);
1371 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1372
1373 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1374 // stream. Should return nothing.
1375 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1376
1377 // Set a sink for an unsignaled stream.
1378 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1379 // Value of "0" means "unsignaled stream".
1380 channel_->SetRawAudioSink(0, std::move(fake_sink));
1381
1382 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1383 // in this method means "unsignaled stream".
1384 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1385 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1386 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1387
1388 // Receive PCMU packet (SSRC=1).
1389 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1390
1391 // The |ssrc| member should still be unset.
1392 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1393 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1394 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1395}
1396
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397// Test that we apply codecs properly.
1398TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001399 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 cricket::AudioSendParameters parameters;
1401 parameters.codecs.push_back(kIsacCodec);
1402 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001403 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001404 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001405 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001407 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1408 EXPECT_EQ(96, send_codec_spec.payload_type);
1409 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1410 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1411 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001412 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001413 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414}
1415
ossu20a4b3f2017-04-27 02:08:52 -07001416// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1417// AudioSendStream.
1418TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kIsacCodec);
1422 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001423 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 parameters.codecs[0].id = 96;
1425 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001426 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001427 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001428 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001429 // Calling SetSendCodec again with same codec which is already set.
1430 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001433}
1434
ossu20a4b3f2017-04-27 02:08:52 -07001435// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1436// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001437
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001438// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].bitrate = 0;
1444 parameters.codecs[0].clockrate = 50000;
1445 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001448// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].bitrate = 0;
1454 parameters.codecs[0].channels = 0;
1455 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456}
1457
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001458// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001460 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001461 cricket::AudioSendParameters parameters;
1462 parameters.codecs.push_back(kOpusCodec);
1463 parameters.codecs[0].bitrate = 0;
1464 parameters.codecs[0].channels = 0;
1465 parameters.codecs[0].params["stereo"] = "1";
1466 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467}
1468
1469// Test that if channel is 1 for opus and there's no stereo, we fail.
1470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 0;
1475 parameters.codecs[0].channels = 1;
1476 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477}
1478
1479// Test that if channel is 1 for opus and stereo=0, we fail.
1480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 0;
1485 parameters.codecs[0].channels = 1;
1486 parameters.codecs[0].params["stereo"] = "0";
1487 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
1490// Test that if channel is 1 for opus and stereo=1, we fail.
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001492 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001493 cricket::AudioSendParameters parameters;
1494 parameters.codecs.push_back(kOpusCodec);
1495 parameters.codecs[0].bitrate = 0;
1496 parameters.codecs[0].channels = 1;
1497 parameters.codecs[0].params["stereo"] = "1";
1498 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499}
1500
ossu20a4b3f2017-04-27 02:08:52 -07001501// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001502TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001503 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001504 cricket::AudioSendParameters parameters;
1505 parameters.codecs.push_back(kOpusCodec);
1506 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509}
1510
ossu20a4b3f2017-04-27 02:08:52 -07001511// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001513 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001514 cricket::AudioSendParameters parameters;
1515 parameters.codecs.push_back(kOpusCodec);
1516 parameters.codecs[0].bitrate = 0;
1517 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001518 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001519 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001520}
1521
ossu20a4b3f2017-04-27 02:08:52 -07001522// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001523TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001524 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001525 cricket::AudioSendParameters parameters;
1526 parameters.codecs.push_back(kOpusCodec);
1527 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001528 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001531 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001532
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001534 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001535 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001536}
1537
ossu20a4b3f2017-04-27 02:08:52 -07001538// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001540 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 cricket::AudioSendParameters parameters;
1542 parameters.codecs.push_back(kOpusCodec);
1543 parameters.codecs[0].bitrate = 0;
1544 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001546 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
ossu20a4b3f2017-04-27 02:08:52 -07001549// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001551 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 cricket::AudioSendParameters parameters;
1553 parameters.codecs.push_back(kOpusCodec);
1554 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001555 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001558 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001559
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001560 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001561 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001562 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001563}
1564
ossu20a4b3f2017-04-27 02:08:52 -07001565// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001567 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001568 cricket::AudioSendParameters parameters;
1569 parameters.codecs.push_back(kOpusCodec);
1570 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001571 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001572 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1573 EXPECT_EQ(111, spec.payload_type);
1574 EXPECT_EQ(96000, spec.target_bitrate_bps);
1575 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001576 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001577 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578}
1579
ossu20a4b3f2017-04-27 02:08:52 -07001580// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].bitrate = 30000;
1586 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001587 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001588 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589}
1590
ossu20a4b3f2017-04-27 02:08:52 -07001591// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001593 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001594 cricket::AudioSendParameters parameters;
1595 parameters.codecs.push_back(kOpusCodec);
1596 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001597 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001598 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599}
1600
ossu20a4b3f2017-04-27 02:08:52 -07001601// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001602TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001603 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001604 cricket::AudioSendParameters parameters;
1605 parameters.codecs.push_back(kOpusCodec);
1606 parameters.codecs[0].bitrate = 30000;
1607 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001608 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001609 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001610}
1611
stefan13f1a0a2016-11-30 07:22:58 -08001612TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1613 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1614 200000);
1615}
1616
1617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1618 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1619}
1620
1621TEST_F(WebRtcVoiceEngineTestFake,
1622 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1623 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1624}
1625
1626TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1627 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1628}
1629
Yves Gerey665174f2018-06-19 15:03:05 +02001630TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001631 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1632 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001633 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001634 // Setting max bitrate should keep previous min bitrate
1635 // Setting max bitrate should not reset start bitrate.
1636 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1637 SetSdpBitrateParameters(
1638 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1639 Field(&BitrateConstraints::start_bitrate_bps, -1),
1640 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001641 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001642}
1643
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001644// Test that we can enable NACK with opus as callee.
1645TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001646 EXPECT_TRUE(SetupRecvStream());
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, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001652 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001653 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001655
Yves Gerey665174f2018-06-19 15:03:05 +02001656 EXPECT_TRUE(
1657 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001658}
1659
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001660// Test that we can enable NACK on receive streams.
1661TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001662 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001663 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 cricket::AudioSendParameters parameters;
1665 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001666 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1667 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001668 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001669 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001670 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671}
1672
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001673// Test that we can disable NACK on receive streams.
1674TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001675 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001677 cricket::AudioSendParameters parameters;
1678 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001679 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1680 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001682 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001684 parameters.codecs.clear();
1685 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001687 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688}
1689
1690// Test that NACK is enabled on a new receive stream.
1691TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001692 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 cricket::AudioSendParameters parameters;
1694 parameters.codecs.push_back(kIsacCodec);
1695 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001696 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1697 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001699
solenberg2100c0b2017-03-01 11:29:29 -08001700 EXPECT_TRUE(AddRecvStream(kSsrcY));
1701 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1702 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1703 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001704}
1705
stefanba4c0e42016-02-04 04:12:24 -08001706TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001707 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001708 cricket::AudioSendParameters send_parameters;
1709 send_parameters.codecs.push_back(kOpusCodec);
1710 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001712
1713 cricket::AudioRecvParameters recv_parameters;
1714 recv_parameters.codecs.push_back(kIsacCodec);
1715 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001716 EXPECT_TRUE(AddRecvStream(kSsrcX));
1717 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001718 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001719 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001720
ossudedfd282016-06-14 07:12:39 -07001721 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001723 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001724 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001725 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001726}
1727
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001728// Test that we can switch back and forth between Opus and ISAC with CN.
1729TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001730 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001731
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001732 cricket::AudioSendParameters opus_parameters;
1733 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001735 {
ossu20a4b3f2017-04-27 02:08:52 -07001736 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1737 EXPECT_EQ(111, spec.payload_type);
1738 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001739 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001740
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001741 cricket::AudioSendParameters isac_parameters;
1742 isac_parameters.codecs.push_back(kIsacCodec);
1743 isac_parameters.codecs.push_back(kCn16000Codec);
1744 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001746 {
ossu20a4b3f2017-04-27 02:08:52 -07001747 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1748 EXPECT_EQ(103, spec.payload_type);
1749 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001750 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001751
solenberg059fb442016-10-26 05:12:24 -07001752 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001753 {
ossu20a4b3f2017-04-27 02:08:52 -07001754 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1755 EXPECT_EQ(111, spec.payload_type);
1756 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001757 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758}
1759
1760// Test that we handle various ways of specifying bitrate.
1761TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001762 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001763 cricket::AudioSendParameters parameters;
1764 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001765 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001766 {
ossu20a4b3f2017-04-27 02:08:52 -07001767 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1768 EXPECT_EQ(103, spec.payload_type);
1769 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1770 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001771 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001772
Yves Gerey665174f2018-06-19 15:03:05 +02001773 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001774 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001775 {
ossu20a4b3f2017-04-27 02:08:52 -07001776 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1777 EXPECT_EQ(103, spec.payload_type);
1778 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1779 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001780 }
Yves Gerey665174f2018-06-19 15:03:05 +02001781 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001783 {
ossu20a4b3f2017-04-27 02:08:52 -07001784 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1785 EXPECT_EQ(103, spec.payload_type);
1786 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1787 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001788 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789
Yves Gerey665174f2018-06-19 15:03:05 +02001790 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 {
ossu20a4b3f2017-04-27 02:08:52 -07001793 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1794 EXPECT_EQ(0, spec.payload_type);
1795 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1796 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001797 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798
Yves Gerey665174f2018-06-19 15:03:05 +02001799 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001800 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001801 {
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_EQ(0, spec.payload_type);
1804 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1805 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001806 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001808 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001809 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001810 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001811 {
ossu20a4b3f2017-04-27 02:08:52 -07001812 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1813 EXPECT_EQ(111, spec.payload_type);
1814 EXPECT_STREQ("opus", spec.format.name.c_str());
1815 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001816 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817}
1818
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001819// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001820TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001821 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 cricket::AudioSendParameters parameters;
1823 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001824}
1825
1826// Test that we can set send codecs even with telephone-event codec as the first
1827// one on the list.
1828TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001829 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001830 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001831 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001832 parameters.codecs.push_back(kIsacCodec);
1833 parameters.codecs.push_back(kPcmuCodec);
1834 parameters.codecs[0].id = 98; // DTMF
1835 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001837 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1838 EXPECT_EQ(96, spec.payload_type);
1839 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001840 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001841 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001842}
1843
Harald Alvestranda1f66612018-02-21 11:24:23 +01001844// Test that CanInsertDtmf() is governed by the send flag
1845TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1846 EXPECT_TRUE(SetupSendStream());
1847 cricket::AudioSendParameters parameters;
1848 parameters.codecs.push_back(kTelephoneEventCodec1);
1849 parameters.codecs.push_back(kPcmuCodec);
1850 parameters.codecs[0].id = 98; // DTMF
1851 parameters.codecs[1].id = 96;
1852 SetSendParameters(parameters);
1853 EXPECT_FALSE(channel_->CanInsertDtmf());
1854 SetSend(true);
1855 EXPECT_TRUE(channel_->CanInsertDtmf());
1856 SetSend(false);
1857 EXPECT_FALSE(channel_->CanInsertDtmf());
1858}
1859
solenberg31642aa2016-03-14 08:00:37 -07001860// Test that payload type range is limited for telephone-event codec.
1861TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001862 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001863 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001864 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001865 parameters.codecs.push_back(kIsacCodec);
1866 parameters.codecs[0].id = 0; // DTMF
1867 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001868 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001869 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001870 EXPECT_TRUE(channel_->CanInsertDtmf());
1871 parameters.codecs[0].id = 128; // DTMF
1872 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1873 EXPECT_FALSE(channel_->CanInsertDtmf());
1874 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001875 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001876 EXPECT_TRUE(channel_->CanInsertDtmf());
1877 parameters.codecs[0].id = -1; // DTMF
1878 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1879 EXPECT_FALSE(channel_->CanInsertDtmf());
1880}
1881
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001882// Test that we can set send codecs even with CN codec as the first
1883// one on the list.
1884TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001885 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 cricket::AudioSendParameters parameters;
1887 parameters.codecs.push_back(kCn16000Codec);
1888 parameters.codecs.push_back(kIsacCodec);
1889 parameters.codecs.push_back(kPcmuCodec);
1890 parameters.codecs[0].id = 98; // wideband CN
1891 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_EQ(96, send_codec_spec.payload_type);
1895 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897}
1898
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001899// Test that we set VAD and DTMF types correctly as caller.
1900TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001901 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001902 cricket::AudioSendParameters parameters;
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001905 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 parameters.codecs.push_back(kCn16000Codec);
1907 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001908 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 parameters.codecs[0].id = 96;
1910 parameters.codecs[2].id = 97; // wideband CN
1911 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001913 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1914 EXPECT_EQ(96, send_codec_spec.payload_type);
1915 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001916 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001917 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001918 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001919 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920}
1921
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001922// Test that we set VAD and DTMF types correctly as callee.
1923TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001924 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001925 cricket::AudioSendParameters parameters;
1926 parameters.codecs.push_back(kIsacCodec);
1927 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001928 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 parameters.codecs.push_back(kCn16000Codec);
1930 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001931 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 parameters.codecs[0].id = 96;
1933 parameters.codecs[2].id = 97; // wideband CN
1934 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001935 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001936 EXPECT_TRUE(
1937 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001938
ossu20a4b3f2017-04-27 02:08:52 -07001939 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1940 EXPECT_EQ(96, send_codec_spec.payload_type);
1941 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001942 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001943 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001944 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001945 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001946}
1947
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948// Test that we only apply VAD if we have a CN codec that matches the
1949// send codec clockrate.
1950TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001951 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001952 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001953 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001954 parameters.codecs.push_back(kIsacCodec);
1955 parameters.codecs.push_back(kCn16000Codec);
1956 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001957 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001958 {
ossu20a4b3f2017-04-27 02:08:52 -07001959 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1960 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001961 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001962 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001963 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001964 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001965 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001966 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001967 {
ossu20a4b3f2017-04-27 02:08:52 -07001968 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1969 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001970 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001971 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001972 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001973 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001974 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001975 {
ossu20a4b3f2017-04-27 02:08:52 -07001976 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1977 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001978 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001979 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001980 }
Brave Yao5225dd82015-03-26 07:39:19 +08001981 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001984 {
ossu20a4b3f2017-04-27 02:08:52 -07001985 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1986 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001987 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001988 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001989}
1990
1991// Test that we perform case-insensitive matching of codec names.
1992TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001993 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001994 cricket::AudioSendParameters parameters;
1995 parameters.codecs.push_back(kIsacCodec);
1996 parameters.codecs.push_back(kPcmuCodec);
1997 parameters.codecs.push_back(kCn16000Codec);
1998 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001999 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002000 parameters.codecs[0].name = "iSaC";
2001 parameters.codecs[0].id = 96;
2002 parameters.codecs[2].id = 97; // wideband CN
2003 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002005 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2006 EXPECT_EQ(96, send_codec_spec.payload_type);
2007 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002008 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002009 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002010 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002011 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012}
2013
stefanba4c0e42016-02-04 04:12:24 -08002014class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2015 public:
2016 WebRtcVoiceEngineWithSendSideBweTest()
2017 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2018};
2019
2020TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2021 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002022 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2023 EXPECT_THAT(capabilities.header_extensions,
2024 Contains(testing::Field(
2025 "uri", &RtpExtension::uri,
2026 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002027}
2028
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002029// Test support for audio level header extension.
2030TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002031 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002032}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002033TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002034 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002035}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002036
solenbergd4adce42016-11-17 06:26:52 -08002037// Test support for transport sequence number header extension.
2038TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2039 TestSetSendRtpHeaderExtensions(
2040 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002041}
solenbergd4adce42016-11-17 06:26:52 -08002042TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2043 TestSetRecvRtpHeaderExtensions(
2044 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002045}
2046
solenberg1ac56142015-10-13 03:58:19 -07002047// Test that we can create a channel and start sending on it.
2048TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002049 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002050 SetSendParameters(send_parameters_);
2051 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002052 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002053 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002054 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002055}
2056
2057// Test that a channel will send if and only if it has a source and is enabled
2058// for sending.
2059TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002060 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002061 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002062 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002063 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002064 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2065 SetAudioSend(kSsrcX, true, &fake_source_);
2066 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2067 SetAudioSend(kSsrcX, true, nullptr);
2068 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002069}
2070
solenberg94218532016-06-16 10:53:22 -07002071// Test that a channel is muted/unmuted.
2072TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2073 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002074 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002075 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2076 SetAudioSend(kSsrcX, true, nullptr);
2077 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2078 SetAudioSend(kSsrcX, false, nullptr);
2079 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002080}
2081
solenberg6d6e7c52016-04-13 09:07:30 -07002082// Test that SetSendParameters() does not alter a stream's send state.
2083TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2084 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002086
2087 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002088 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002089 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002090
2091 // Changing RTP header extensions will recreate the AudioSendStream.
2092 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002093 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002094 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002095 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002096
2097 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002098 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002099 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002100
2101 // Changing RTP header extensions will recreate the AudioSendStream.
2102 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002103 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105}
2106
solenberg1ac56142015-10-13 03:58:19 -07002107// Test that we can create a channel and start playing out on it.
2108TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002109 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002110 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002111 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002113 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002115}
2116
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117// Test that we can add and remove send streams.
2118TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2119 SetupForMultiSendStream();
2120
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002121 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002122 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123
solenbergc96df772015-10-21 13:01:53 -07002124 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002125 EXPECT_TRUE(
2126 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002127 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002129 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130 }
tfarina5237aaf2015-11-10 23:44:30 -08002131 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132
solenbergc96df772015-10-21 13:01:53 -07002133 // Delete the send streams.
2134 for (uint32_t ssrc : kSsrcs4) {
2135 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002136 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002137 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 }
solenbergc96df772015-10-21 13:01:53 -07002139 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140}
2141
2142// Test SetSendCodecs correctly configure the codecs in all send streams.
2143TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2144 SetupForMultiSendStream();
2145
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002147 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002148 EXPECT_TRUE(
2149 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150 }
2151
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002152 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002154 parameters.codecs.push_back(kIsacCodec);
2155 parameters.codecs.push_back(kCn16000Codec);
2156 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002157 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158
2159 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002160 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002161 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2162 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002163 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2164 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002165 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002166 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002167 }
2168
minyue7a973442016-10-20 03:27:12 -07002169 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002170 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002171 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002172 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002173 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2174 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002175 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2176 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002177 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002178 }
2179}
2180
2181// Test we can SetSend on all send streams correctly.
2182TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2183 SetupForMultiSendStream();
2184
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002185 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002186 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002187 EXPECT_TRUE(
2188 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002189 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002190 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002191 }
2192
2193 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002194 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002195 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002196 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002197 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002198 }
2199
2200 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002201 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002202 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002204 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002205 }
2206}
2207
2208// Test we can set the correct statistics on all send streams.
2209TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2210 SetupForMultiSendStream();
2211
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002213 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002214 EXPECT_TRUE(
2215 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216 }
solenberg85a04962015-10-27 03:35:21 -07002217
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002218 // Create a receive stream to check that none of the send streams end up in
2219 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002220 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002221
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002222 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002223 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002224 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002225 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002226
solenberg85a04962015-10-27 03:35:21 -07002227 // Check stats for the added streams.
2228 {
2229 cricket::VoiceMediaInfo info;
2230 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231
solenberg85a04962015-10-27 03:35:21 -07002232 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002233 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002234 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002235 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002236 }
hbos1acfbd22016-11-17 23:43:29 -08002237 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002238
2239 // We have added one receive stream. We should see empty stats.
2240 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002241 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002242 }
solenberg1ac56142015-10-13 03:58:19 -07002243
solenberg2100c0b2017-03-01 11:29:29 -08002244 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002245 {
2246 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002247 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002248 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002249 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002250 EXPECT_EQ(0u, info.receivers.size());
2251 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002252
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002253 // Deliver a new packet - a default receive stream should be created and we
2254 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002255 {
2256 cricket::VoiceMediaInfo info;
2257 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2258 SetAudioReceiveStreamStats();
2259 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002260 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002261 EXPECT_EQ(1u, info.receivers.size());
2262 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002263 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002264 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002265}
2266
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002267// Test that we can add and remove receive streams, and do proper send/playout.
2268// We can receive on multiple streams while sending one stream.
2269TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002270 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002271
solenberg1ac56142015-10-13 03:58:19 -07002272 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002273 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002274 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002275
solenberg1ac56142015-10-13 03:58:19 -07002276 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002277 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002278 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002279 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002280
solenberg1ac56142015-10-13 03:58:19 -07002281 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002282 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002283
2284 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2286 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2287 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288
2289 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002290 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002291 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
2293 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002294 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002295 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2296 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002297
aleloi84ef6152016-08-04 05:28:21 -07002298 // Restart playout and make sure recv streams are played out.
2299 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2301 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002302
aleloi84ef6152016-08-04 05:28:21 -07002303 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002304 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2305 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002306}
2307
wu@webrtc.org97077a32013-10-25 21:18:33 +00002308TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002309 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002310 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2311 .Times(1)
2312 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002313 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2314 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002315 send_parameters_.options.tx_agc_target_dbov = 3;
2316 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2317 send_parameters_.options.tx_agc_limiter = true;
2318 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002319 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2320 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2321 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002322 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002323}
2324
minyue6b825df2016-10-31 04:08:32 -07002325TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2326 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002327 send_parameters_.options.audio_network_adaptor = true;
2328 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002329 SetSendParameters(send_parameters_);
2330 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002331 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002332}
2333
2334TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
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 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002342 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002343 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002344 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002345}
2346
2347TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2348 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002349 send_parameters_.options.audio_network_adaptor = true;
2350 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002351 SetSendParameters(send_parameters_);
2352 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002353 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002354 const int initial_num = call_.GetNumCreatedSendStreams();
2355 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002356 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002357 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2358 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002359 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002360 // AudioSendStream not expected to be recreated.
2361 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2362 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002363 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002364}
2365
michaelt6672b262017-01-11 10:17:59 -08002366class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2367 : public WebRtcVoiceEngineTestFake {
2368 public:
2369 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2370 : WebRtcVoiceEngineTestFake(
2371 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2372 "Enabled/") {}
2373};
2374
2375TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2376 EXPECT_TRUE(SetupSendStream());
2377 cricket::AudioSendParameters parameters;
2378 parameters.codecs.push_back(kOpusCodec);
2379 SetSendParameters(parameters);
2380 const int initial_num = call_.GetNumCreatedSendStreams();
2381 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2382
2383 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2384 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002385 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2386 constexpr int kMinOverheadBps =
2387 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002388
2389 constexpr int kOpusMinBitrateBps = 6000;
2390 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002391 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002392 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002393 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002394 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002395
Oskar Sundbom78807582017-11-16 11:09:55 +01002396 parameters.options.audio_network_adaptor = true;
2397 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002398 SetSendParameters(parameters);
2399
ossu11bfc532017-02-16 05:37:06 -08002400 constexpr int kMinOverheadWithAnaBps =
2401 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002402
2403 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002404 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002405
minyuececec102017-03-27 13:04:25 -07002406 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002407 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002408}
2409
minyuececec102017-03-27 13:04:25 -07002410// This test is similar to
2411// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2412// additional field trial.
2413TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2414 SetRtpSendParameterUpdatesMaxBitrate) {
2415 EXPECT_TRUE(SetupSendStream());
2416 cricket::AudioSendParameters send_parameters;
2417 send_parameters.codecs.push_back(kOpusCodec);
2418 SetSendParameters(send_parameters);
2419
2420 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2421 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2422 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2423
2424 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002425 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002426 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002427
2428 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2429#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2430 constexpr int kMinOverhead = 3333;
2431#else
2432 constexpr int kMinOverhead = 6666;
2433#endif
2434 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2435}
2436
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002438// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002440 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002441 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002442}
2443
2444TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2445 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002446 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002447 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002448 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002449 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002450 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002451 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002452 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453
solenberg85a04962015-10-27 03:35:21 -07002454 // Check stats for the added streams.
2455 {
2456 cricket::VoiceMediaInfo info;
2457 EXPECT_EQ(true, channel_->GetStats(&info));
2458
2459 // We have added one send stream. We should see the stats we've set.
2460 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002461 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002462 // We have added one receive stream. We should see empty stats.
2463 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002464 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002465 }
solenberg1ac56142015-10-13 03:58:19 -07002466
solenberg566ef242015-11-06 15:34:49 -08002467 // Start sending - this affects some reported stats.
2468 {
2469 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002470 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002471 EXPECT_EQ(true, channel_->GetStats(&info));
2472 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002473 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002474 }
2475
solenberg2100c0b2017-03-01 11:29:29 -08002476 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002477 {
2478 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002480 EXPECT_EQ(true, channel_->GetStats(&info));
2481 EXPECT_EQ(1u, info.senders.size());
2482 EXPECT_EQ(0u, info.receivers.size());
2483 }
solenberg1ac56142015-10-13 03:58:19 -07002484
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002485 // Deliver a new packet - a default receive stream should be created and we
2486 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002487 {
2488 cricket::VoiceMediaInfo info;
2489 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2490 SetAudioReceiveStreamStats();
2491 EXPECT_EQ(true, channel_->GetStats(&info));
2492 EXPECT_EQ(1u, info.senders.size());
2493 EXPECT_EQ(1u, info.receivers.size());
2494 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002495 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002496 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497}
2498
2499// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002500// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002502 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002503 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2504 EXPECT_TRUE(AddRecvStream(kSsrcY));
2505 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506}
2507
2508// Test that the local SSRC is the same on sending and receiving channels if the
2509// receive channel is created before the send channel.
2510TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002511 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002512 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002513 EXPECT_TRUE(
2514 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002515 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2516 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002517}
2518
2519// Test that we can properly receive packets.
2520TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002521 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002522 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002524
Yves Gerey665174f2018-06-19 15:03:05 +02002525 EXPECT_TRUE(
2526 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527}
2528
2529// Test that we can properly receive packets on multiple streams.
2530TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002531 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002532 const uint32_t ssrc1 = 1;
2533 const uint32_t ssrc2 = 2;
2534 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002535 EXPECT_TRUE(AddRecvStream(ssrc1));
2536 EXPECT_TRUE(AddRecvStream(ssrc2));
2537 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002539 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002540 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002541 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002542 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543 }
mflodman3d7db262016-04-29 00:57:13 -07002544
2545 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2546 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2547 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2548
2549 EXPECT_EQ(s1.received_packets(), 0);
2550 EXPECT_EQ(s2.received_packets(), 0);
2551 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002552
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002553 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002554 EXPECT_EQ(s1.received_packets(), 0);
2555 EXPECT_EQ(s2.received_packets(), 0);
2556 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002557
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002558 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002559 EXPECT_EQ(s1.received_packets(), 1);
2560 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2561 EXPECT_EQ(s2.received_packets(), 0);
2562 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002563
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002565 EXPECT_EQ(s1.received_packets(), 1);
2566 EXPECT_EQ(s2.received_packets(), 1);
2567 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2568 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002569
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002570 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002571 EXPECT_EQ(s1.received_packets(), 1);
2572 EXPECT_EQ(s2.received_packets(), 1);
2573 EXPECT_EQ(s3.received_packets(), 1);
2574 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002575
mflodman3d7db262016-04-29 00:57:13 -07002576 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2577 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2578 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002579}
2580
solenberg2100c0b2017-03-01 11:29:29 -08002581// Test that receiving on an unsignaled stream works (a stream is created).
2582TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002583 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002584 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002585
solenberg7e63ef02015-11-20 00:19:43 -08002586 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002587
Mirko Bonadeif859e552018-05-30 15:31:29 +02002588 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002589 EXPECT_TRUE(
2590 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002591}
2592
Seth Hampson5897a6e2018-04-03 11:16:33 -07002593// Tests that when we add a stream without SSRCs, but contains a stream_id
2594// that it is stored and its stream id is later used when the first packet
2595// arrives to properly create a receive stream with a sync label.
2596TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2597 const char kSyncLabel[] = "sync_label";
2598 EXPECT_TRUE(SetupChannel());
2599 cricket::StreamParams unsignaled_stream;
2600 unsignaled_stream.set_stream_ids({kSyncLabel});
2601 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2602 // The stream shouldn't have been created at this point because it doesn't
2603 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002604 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002605
2606 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2607
Mirko Bonadeif859e552018-05-30 15:31:29 +02002608 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002609 EXPECT_TRUE(
2610 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2611 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2612
2613 // Removing the unsignaled stream clears the cached parameters. If a new
2614 // default unsignaled receive stream is created it will not have a sync group.
2615 channel_->RemoveRecvStream(0);
2616 channel_->RemoveRecvStream(kSsrc1);
2617
2618 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2619
Mirko Bonadeif859e552018-05-30 15:31:29 +02002620 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002621 EXPECT_TRUE(
2622 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2623 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2624}
2625
solenberg2100c0b2017-03-01 11:29:29 -08002626// Test that receiving N unsignaled stream works (streams will be created), and
2627// that packets are forwarded to them all.
2628TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002629 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002630 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002631 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2632
solenberg2100c0b2017-03-01 11:29:29 -08002633 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002634 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002635 rtc::SetBE32(&packet[8], ssrc);
2636 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002637
solenberg2100c0b2017-03-01 11:29:29 -08002638 // Verify we have one new stream for each loop iteration.
2639 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002640 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2641 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002642 }
mflodman3d7db262016-04-29 00:57:13 -07002643
solenberg2100c0b2017-03-01 11:29:29 -08002644 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002645 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002646 rtc::SetBE32(&packet[8], ssrc);
2647 DeliverPacket(packet, sizeof(packet));
2648
solenbergebb349d2017-03-13 05:46:15 -07002649 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002650 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2651 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2652 }
2653
2654 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2655 constexpr uint32_t kAnotherSsrc = 667;
2656 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002657 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002658
2659 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002660 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002661 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002662 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002663 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2664 EXPECT_EQ(2, streams[i]->received_packets());
2665 }
2666 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2667 EXPECT_EQ(1, streams[i]->received_packets());
2668 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002669 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002670}
2671
solenberg2100c0b2017-03-01 11:29:29 -08002672// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002673// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002674TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002675 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002676 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002677 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2678
2679 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002680 const uint32_t signaled_ssrc = 1;
2681 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002682 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002683 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002684 EXPECT_TRUE(
2685 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002686 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002687
2688 // Note that the first unknown SSRC cannot be 0, because we only support
2689 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002690 const uint32_t unsignaled_ssrc = 7011;
2691 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002692 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002693 EXPECT_TRUE(
2694 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002695 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002696
2697 DeliverPacket(packet, sizeof(packet));
2698 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2699
2700 rtc::SetBE32(&packet[8], signaled_ssrc);
2701 DeliverPacket(packet, sizeof(packet));
2702 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002703 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002704}
2705
solenberg4904fb62017-02-17 12:01:14 -08002706// Two tests to verify that adding a receive stream with the same SSRC as a
2707// previously added unsignaled stream will only recreate underlying stream
2708// objects if the stream parameters have changed.
2709TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2710 EXPECT_TRUE(SetupChannel());
2711
2712 // Spawn unsignaled stream with SSRC=1.
2713 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002714 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002715 EXPECT_TRUE(
2716 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002717
2718 // Verify that the underlying stream object in Call is not recreated when a
2719 // stream with SSRC=1 is added.
2720 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002721 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002722 int audio_receive_stream_id = streams.front()->id();
2723 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002724 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002725 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2726}
2727
2728TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2729 EXPECT_TRUE(SetupChannel());
2730
2731 // Spawn unsignaled stream with SSRC=1.
2732 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002733 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002734 EXPECT_TRUE(
2735 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002736
2737 // Verify that the underlying stream object in Call *is* recreated when a
2738 // stream with SSRC=1 is added, and which has changed stream parameters.
2739 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002740 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002741 int audio_receive_stream_id = streams.front()->id();
2742 cricket::StreamParams stream_params;
2743 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002744 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002745 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002746 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002747 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2748}
2749
solenberg1ac56142015-10-13 03:58:19 -07002750// Test that AddRecvStream creates new stream.
2751TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002752 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002753 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754}
2755
2756// Test that after adding a recv stream, we do not decode more codecs than
2757// those previously passed into SetRecvCodecs.
2758TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002760 cricket::AudioRecvParameters parameters;
2761 parameters.codecs.push_back(kIsacCodec);
2762 parameters.codecs.push_back(kPcmuCodec);
2763 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002764 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002765 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2766 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2767 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768}
2769
2770// Test that we properly clean up any streams that were added, even if
2771// not explicitly removed.
2772TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002773 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002775 EXPECT_TRUE(AddRecvStream(1));
2776 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002777
Mirko Bonadeif859e552018-05-30 15:31:29 +02002778 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2779 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002780 delete channel_;
2781 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002782 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2783 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002784}
2785
wu@webrtc.org78187522013-10-07 23:32:02 +00002786TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002787 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002788 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002789}
2790
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002791TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002792 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002793 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002794 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002795}
2796
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002797// Test the InsertDtmf on default send stream as caller.
2798TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002799 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800}
2801
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002802// Test the InsertDtmf on default send stream as callee
2803TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002804 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002805}
2806
2807// Test the InsertDtmf on specified send stream as caller.
2808TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002809 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002810}
2811
2812// Test the InsertDtmf on specified send stream as callee.
2813TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002814 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002815}
2816
Johannes Kron9190b822018-10-29 11:22:05 +01002817// Test propagation of extmap allow mixed setting.
2818TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2819 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2820}
2821TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2822 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2823}
2824TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2825 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2826}
2827TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2828 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2829}
2830
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002832 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002833 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002834 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2835 .Times(9)
2836 .WillRepeatedly(Return(false));
2837 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2838 .Times(4)
2839 .WillRepeatedly(Return(false));
2840 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2841 .Times(2)
2842 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002843
Mirko Bonadeif859e552018-05-30 15:31:29 +02002844 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002845 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002846
solenberg246b8172015-12-08 09:50:23 -08002847 // Nothing set in AudioOptions, so everything should be as default.
2848 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002849 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002850 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002851 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002852 EXPECT_TRUE(IsTypingDetectionEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002853 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002854 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002855
Sam Zackrissonba502232019-01-04 10:36:48 +01002856 // Turn typing detection off.
2857 send_parameters_.options.typing_detection = false;
2858 SetSendParameters(send_parameters_);
2859 EXPECT_FALSE(IsTypingDetectionEnabled());
2860
2861 // Leave typing detection unchanged, but non-default.
2862 send_parameters_.options.typing_detection = absl::nullopt;
2863 SetSendParameters(send_parameters_);
2864 EXPECT_FALSE(IsTypingDetectionEnabled());
2865
2866 // Turn typing detection on.
2867 send_parameters_.options.typing_detection = true;
2868 SetSendParameters(send_parameters_);
2869 EXPECT_TRUE(IsTypingDetectionEnabled());
2870
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002871 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002873 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002874 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002875
2876 // Turn echo cancellation back on, with settings, and make sure
2877 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002878 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002879 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002880 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002882 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2883 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002885 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002886 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002887
2888 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002889 send_parameters_.options.delay_agnostic_aec = false;
2890 send_parameters_.options.extended_filter_aec = false;
2891 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002892 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002893 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002894
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002895 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002896 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002897 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002898 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002899
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002901 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002902 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002903 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002904 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002905 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906
2907 // Turn AGC back on
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));
Oskar Sundbom78807582017-11-16 11:09:55 +01002910 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002911 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002912 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002914 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002917 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002919 send_parameters_.options.noise_suppression = false;
2920 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002921 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002922 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002923 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002924 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925
solenberg1ac56142015-10-13 03:58:19 -07002926 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002927 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002928 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002929 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002930 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002931 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002932 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933}
2934
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002936 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002937 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2938 .Times(8)
2939 .WillRepeatedly(Return(false));
2940 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2941 .Times(8)
2942 .WillRepeatedly(Return(false));
2943 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2944 .Times(8)
2945 .WillRepeatedly(Return(false));
2946 EXPECT_CALL(adm_, RecordingIsInitialized())
2947 .Times(2)
2948 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002949 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2950 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002951 webrtc::AudioProcessing::Config apm_config;
2952 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002953 .WillRepeatedly(ReturnPointee(&apm_config));
2954 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002955 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002956 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002957
kwiberg686a8ef2016-02-26 03:00:35 -08002958 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002959 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2960 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2961 cricket::AudioOptions(),
2962 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002963 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002964 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2965 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2966 cricket::AudioOptions(),
2967 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968
2969 // Have to add a stream to make SetSend work.
2970 cricket::StreamParams stream1;
2971 stream1.ssrcs.push_back(1);
2972 channel1->AddSendStream(stream1);
2973 cricket::StreamParams stream2;
2974 stream2.ssrcs.push_back(2);
2975 channel2->AddSendStream(stream2);
2976
2977 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002978 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002979 parameters_options_all.options.echo_cancellation = true;
2980 parameters_options_all.options.auto_gain_control = true;
2981 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002982 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002983 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002984 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002985 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002986 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002987 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002988 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002989 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002990 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002991 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
2993 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002994 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002995 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002996 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002997 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002998 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002999 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003000 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003001 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003002 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003003 expected_options.echo_cancellation = true;
3004 expected_options.auto_gain_control = true;
3005 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003006 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007
3008 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003009 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003010 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003011 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003012 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003013 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003014 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003015 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003016 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003017 expected_options.echo_cancellation = true;
3018 expected_options.auto_gain_control = false;
3019 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003020 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003022 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003023 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003024 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003025 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003026 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003027 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003029 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003030 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003031 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003032 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003033 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003034 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003036 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003037 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003038 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003039 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003040 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003041 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003042
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003044 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3045 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003046 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3047 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003048 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003049 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003050 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003051 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003052 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003053 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003054 expected_options.echo_cancellation = true;
3055 expected_options.auto_gain_control = false;
3056 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003057 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003058}
3059
wu@webrtc.orgde305012013-10-31 15:40:38 +00003060// This test verifies DSCP settings are properly applied on voice media channel.
3061TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003062 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003063 cricket::FakeNetworkInterface network_interface;
3064 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003065 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003066 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003067
peahb1c9d1d2017-07-25 15:45:24 -07003068 webrtc::AudioProcessing::Config apm_config;
3069 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003070 .WillRepeatedly(ReturnPointee(&apm_config));
3071 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003072 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003073 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003074
Sebastian Jansson84848f22018-11-16 10:40:36 +01003075 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3076 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3077 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003078 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003079 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3080 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3081
3082 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003083 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3084 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3085 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003086 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003087 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3088
3089 // Create a send stream to configure
3090 EXPECT_TRUE(
3091 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3092 parameters = channel->GetRtpSendParameters(kSsrcZ);
3093 ASSERT_FALSE(parameters.encodings.empty());
3094
3095 // Various priorities map to various dscp values.
3096 parameters.encodings[0].network_priority = 4.0;
3097 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003098 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003099 parameters.encodings[0].network_priority = 0.5;
3100 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3101 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3102
3103 // A bad priority does not change the dscp value.
3104 parameters.encodings[0].network_priority = 0.0;
3105 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3106 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003107
Tim Haloun6ca98362018-09-17 17:06:08 -07003108 // Packets should also self-identify their dscp in PacketOptions.
3109 const uint8_t kData[10] = {0};
3110 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003111 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003112
nisse51542be2016-02-12 02:27:06 -08003113 // Verify that setting the option to false resets the
3114 // DiffServCodePoint.
3115 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003116 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3117 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3118 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003119 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003120 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3121 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3122
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003123 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003124}
3125
solenberg4bac9c52015-10-09 02:32:53 -07003126TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003127 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003128 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003129 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003130 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003131 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003132 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3133 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3134 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003135}
3136
solenberg2100c0b2017-03-01 11:29:29 -08003137TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003138 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003139
3140 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003141 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003142 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3143
3144 // Should remember the volume "2" which will be set on new unsignaled streams,
3145 // and also set the gain to 2 on existing unsignaled streams.
3146 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3147 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3148
3149 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3150 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3151 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3152 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3153 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3154 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3155
3156 // Setting gain with SSRC=0 should affect all unsignaled streams.
3157 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003158 if (kMaxUnsignaledRecvStreams > 1) {
3159 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3160 }
solenberg2100c0b2017-03-01 11:29:29 -08003161 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3162
3163 // Setting gain on an individual stream affects only that.
3164 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003165 if (kMaxUnsignaledRecvStreams > 1) {
3166 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3167 }
solenberg2100c0b2017-03-01 11:29:29 -08003168 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003169}
3170
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003171TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3172 EXPECT_TRUE(SetupChannel());
3173 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3174 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3175
3176 cricket::StreamParams stream;
3177 stream.ssrcs.push_back(kSsrcY);
3178 EXPECT_TRUE(channel_->AddRecvStream(stream));
3179 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3180 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3181 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3182}
3183
3184TEST_F(WebRtcVoiceEngineTestFake,
3185 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3186 // Here base minimum delay is abbreviated to delay in comments for shortness.
3187 EXPECT_TRUE(SetupChannel());
3188
3189 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3190 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3191 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3192 // Check that it doesn't provide default values for unknown ssrc.
3193 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3194
3195 // Check that default value for unsignaled streams is 0.
3196 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3197
3198 // Should remember the delay 100 which will be set on new unsignaled streams,
3199 // and also set the delay to 100 on existing unsignaled streams.
3200 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3201 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3202 // Check that it doesn't provide default values for unknown ssrc.
3203 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3204
3205 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3206 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3207 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3208 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3209 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3210 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3211
3212 // Setting delay with SSRC=0 should affect all unsignaled streams.
3213 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3214 if (kMaxUnsignaledRecvStreams > 1) {
3215 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3216 }
3217 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3218
3219 // Setting delay on an individual stream affects only that.
3220 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3221 if (kMaxUnsignaledRecvStreams > 1) {
3222 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3223 }
3224 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3225 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3226 // Check that it doesn't provide default values for unknown ssrc.
3227 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3228}
3229
Seth Hampson845e8782018-03-02 11:34:10 -08003230TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003231 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003232 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003233
solenbergff976312016-03-30 23:28:51 -07003234 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003235 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003236 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003237 // Creating two channels to make sure that sync label is set properly for both
3238 // the default voice channel and following ones.
3239 EXPECT_TRUE(channel_->AddRecvStream(sp));
3240 sp.ssrcs[0] += 1;
3241 EXPECT_TRUE(channel_->AddRecvStream(sp));
3242
Mirko Bonadeif859e552018-05-30 15:31:29 +02003243 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003244 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003245 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003246 << "SyncGroup should be set based on stream id";
3247 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003248 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003249 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003250}
3251
solenberg3a941542015-11-16 07:34:50 -08003252// TODO(solenberg): Remove, once recv streams are configured through Call.
3253// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003254TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 // Test that setting the header extensions results in the expected state
3256 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003257 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258 ssrcs.push_back(223);
3259 ssrcs.push_back(224);
3260
solenbergff976312016-03-30 23:28:51 -07003261 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003262 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003263 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003264 EXPECT_TRUE(
3265 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003266 }
3267
Mirko Bonadeif859e552018-05-30 15:31:29 +02003268 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003269 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003270 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003272 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 }
3274
3275 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003276 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003277 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003278 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003279 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003280 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003281 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003282 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003283 EXPECT_NE(nullptr, s);
3284 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003285 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3286 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003287 for (const auto& s_ext : s_exts) {
3288 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003289 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003290 }
3291 }
3292 }
3293 }
3294
3295 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003296 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003297 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003298 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003299 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003300 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003301 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003302}
3303
3304TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3305 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003306 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003307 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003308 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003309 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3310 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003312 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003313
solenbergff976312016-03-30 23:28:51 -07003314 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003315 cricket::WebRtcVoiceMediaChannel* media_channel =
3316 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003317 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003318 EXPECT_TRUE(media_channel->AddRecvStream(
3319 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3320
Mirko Bonadeif859e552018-05-30 15:31:29 +02003321 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003322 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003323 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003324 EXPECT_EQ(0, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003325 channel_->OnPacketReceived(&kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003326 EXPECT_EQ(1, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003327 channel_->OnRtcpReceived(&kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003328 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003329}
Minyue2013aec2015-05-13 14:14:42 +02003330
solenberg0a617e22015-10-20 15:49:38 -07003331// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003332// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003333TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003334 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003335 EXPECT_TRUE(AddRecvStream(kSsrcY));
3336 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003337 EXPECT_TRUE(
3338 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003339 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3340 EXPECT_TRUE(AddRecvStream(kSsrcW));
3341 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003342}
3343
solenberg7602aab2016-11-14 11:30:07 -08003344TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3345 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003347 EXPECT_TRUE(
3348 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003349 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3350 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3351 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003352 EXPECT_TRUE(
3353 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003354 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3355 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003356}
stefan658910c2015-09-03 05:48:32 -07003357
deadbeef884f5852016-01-15 09:20:04 -08003358TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003359 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003360 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3361 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003362
3363 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003364 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3365 EXPECT_TRUE(AddRecvStream(kSsrcX));
3366 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003367
3368 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003369 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3370 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003371
3372 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003373 channel_->SetRawAudioSink(kSsrcX, nullptr);
3374 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003375}
3376
solenberg2100c0b2017-03-01 11:29:29 -08003377TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003378 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003379 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3380 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003381 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3382 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003383
3384 // Should be able to set a default sink even when no stream exists.
3385 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3386
solenberg2100c0b2017-03-01 11:29:29 -08003387 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3388 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003389 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003390 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003391
3392 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003393 channel_->SetRawAudioSink(kSsrc0, nullptr);
3394 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003395
3396 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003397 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3398 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003399
3400 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003401 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003402 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003403 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3404
3405 // Spawn another unsignaled stream - it should be assigned the default sink
3406 // and the previous unsignaled stream should lose it.
3407 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3408 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3409 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3410 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003411 if (kMaxUnsignaledRecvStreams > 1) {
3412 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3413 }
solenberg2100c0b2017-03-01 11:29:29 -08003414 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3415
3416 // Reset the default sink - the second unsignaled stream should lose it.
3417 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003418 if (kMaxUnsignaledRecvStreams > 1) {
3419 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3420 }
solenberg2100c0b2017-03-01 11:29:29 -08003421 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3422
3423 // Try setting the default sink while two streams exists.
3424 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003425 if (kMaxUnsignaledRecvStreams > 1) {
3426 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3427 }
solenberg2100c0b2017-03-01 11:29:29 -08003428 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3429
3430 // Try setting the sink for the first unsignaled stream using its known SSRC.
3431 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003432 if (kMaxUnsignaledRecvStreams > 1) {
3433 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3434 }
solenberg2100c0b2017-03-01 11:29:29 -08003435 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003436 if (kMaxUnsignaledRecvStreams > 1) {
3437 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3438 }
deadbeef884f5852016-01-15 09:20:04 -08003439}
3440
skvlad7a43d252016-03-22 15:32:27 -07003441// Test that, just like the video channel, the voice channel communicates the
3442// network state to the call.
3443TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003444 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003445
3446 EXPECT_EQ(webrtc::kNetworkUp,
3447 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3448 EXPECT_EQ(webrtc::kNetworkUp,
3449 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3450
3451 channel_->OnReadyToSend(false);
3452 EXPECT_EQ(webrtc::kNetworkDown,
3453 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3454 EXPECT_EQ(webrtc::kNetworkUp,
3455 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3456
3457 channel_->OnReadyToSend(true);
3458 EXPECT_EQ(webrtc::kNetworkUp,
3459 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3460 EXPECT_EQ(webrtc::kNetworkUp,
3461 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3462}
3463
aleloi18e0b672016-10-04 02:45:47 -07003464// Test that playout is still started after changing parameters
3465TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3466 SetupRecvStream();
3467 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003468 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003469
3470 // Changing RTP header extensions will recreate the AudioReceiveStream.
3471 cricket::AudioRecvParameters parameters;
3472 parameters.extensions.push_back(
3473 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3474 channel_->SetRecvParameters(parameters);
3475
solenberg2100c0b2017-03-01 11:29:29 -08003476 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003477}
3478
Zhi Huangfa266ef2017-12-13 10:27:46 -08003479// Tests when GetSources is called with non-existing ssrc, it will return an
3480// empty list of RtpSource without crashing.
3481TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3482 // Setup an recv stream with |kSsrcX|.
3483 SetupRecvStream();
3484 cricket::WebRtcVoiceMediaChannel* media_channel =
3485 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3486 // Call GetSources with |kSsrcY| which doesn't exist.
3487 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3488 EXPECT_EQ(0u, sources.size());
3489}
3490
stefan658910c2015-09-03 05:48:32 -07003491// Tests that the library initializes and shuts down properly.
3492TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003493 // If the VoiceEngine wants to gather available codecs early, that's fine but
3494 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003495 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003496 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003497 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003498 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003499 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003500 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003501 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003502 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003503 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003504 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003505 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3506 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3507 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003508 EXPECT_TRUE(channel != nullptr);
3509 delete channel;
solenbergff976312016-03-30 23:28:51 -07003510}
stefan658910c2015-09-03 05:48:32 -07003511
solenbergff976312016-03-30 23:28:51 -07003512// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003513TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3514 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003515 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003516 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003517 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003518 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003519 {
peaha9cc40b2017-06-29 08:32:09 -07003520 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003521 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003522 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003523 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003524 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003525 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003526 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003527 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003528 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003529 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3530 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3531 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003532 EXPECT_TRUE(channel != nullptr);
3533 delete channel;
3534 }
stefan658910c2015-09-03 05:48:32 -07003535}
3536
ossu20a4b3f2017-04-27 02:08:52 -07003537// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3538TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003539 // TODO(ossu): Why are the payload types of codecs with non-static payload
3540 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003541 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003542 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003543 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003544 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003545 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003546 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003547 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003548 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003549 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003550 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003551 (clockrate == 0 || codec.clockrate == clockrate);
3552 };
3553 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003554 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003555 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003556 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003557 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003558 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003559 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003560 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003561 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003562 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003563 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003564 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003565 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3566 // Remove these checks once both send and receive side assigns payload
3567 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003568 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003569 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003570 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003571 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003572 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003573 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003574 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003575 EXPECT_EQ(111, codec.id);
3576 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3577 EXPECT_EQ("10", codec.params.find("minptime")->second);
3578 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3579 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003580 }
3581 }
stefan658910c2015-09-03 05:48:32 -07003582}
3583
3584// Tests that VoE supports at least 32 channels
3585TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003586 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003587 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003588 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003589 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003590 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003591 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003592 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003593 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003594 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003595 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003596
3597 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003598 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003599 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003600 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3601 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3602 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003603 if (!channel)
3604 break;
stefan658910c2015-09-03 05:48:32 -07003605 channels[num_channels++] = channel;
3606 }
3607
Mirko Bonadeif859e552018-05-30 15:31:29 +02003608 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003609 EXPECT_EQ(expected, num_channels);
3610
3611 while (num_channels > 0) {
3612 delete channels[--num_channels];
3613 }
stefan658910c2015-09-03 05:48:32 -07003614}
3615
3616// Test that we set our preferred codecs properly.
3617TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003618 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3619 // - Check that our builtin codecs are usable by Channel.
3620 // - The codecs provided by the engine is usable by Channel.
3621 // It does not check that the codecs in the RecvParameters are actually
3622 // what we sent in - though it's probably reasonable to expect so, if
3623 // SetRecvParameters returns true.
3624 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003625 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003626 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003627 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003628 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003629 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003630 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003631 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003632 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003633 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003634 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003635 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003636 cricket::AudioOptions(),
3637 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003638 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003639 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003640 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003641}
ossu9def8002017-02-09 05:14:32 -08003642
3643TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3644 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003645 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3646 {48000, 2, 16000, 10000, 20000}};
3647 spec1.info.allow_comfort_noise = false;
3648 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003649 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003650 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3651 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003652 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003653 specs.push_back(webrtc::AudioCodecSpec{
3654 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3655 {16000, 1, 13300}});
3656 specs.push_back(
3657 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3658 specs.push_back(
3659 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003660
ossueb1fde42017-05-02 06:46:30 -07003661 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3662 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3663 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003664 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003665 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003666 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003667 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003668
peaha9cc40b2017-06-29 08:32:09 -07003669 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003670 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003671 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003672 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003673 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003674 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003675 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003676
3677 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3678 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003679 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3680 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3681 if (codecs.size() > index)
3682 return codecs[index];
3683 return missing_codec;
3684 };
ossu9def8002017-02-09 05:14:32 -08003685
3686 // Ensure the general codecs are generated first and in order.
3687 for (size_t i = 0; i != specs.size(); ++i) {
3688 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3689 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3690 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3691 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3692 }
3693
3694 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003695 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003696 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3697 for (size_t i = 0; i != codecs.size(); ++i) {
3698 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003699 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003700 codec.clockrate == format.clockrate_hz &&
3701 codec.channels == format.num_channels) {
3702 return rtc::checked_cast<int>(i);
3703 }
3704 }
3705 return -1;
3706 };
ossu9def8002017-02-09 05:14:32 -08003707
3708 // Ensure all supplementary codecs are generated last. Their internal ordering
3709 // is not important.
3710 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3711 const int num_specs = static_cast<int>(specs.size());
3712 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3713 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3714 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3715 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3716 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3717 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3718 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3719}