blob: 65f3c7b33c3ae69bccc6833e019323ea06fb1e02 [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"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070017#include "api/media_transport_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010019#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010020#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "call/call.h"
22#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "media/base/fake_media_engine.h"
24#include "media/base/fake_network_interface.h"
25#include "media/base/fake_rtp.h"
26#include "media/base/media_constants.h"
27#include "media/engine/fake_webrtc_call.h"
28#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "modules/audio_device/include/mock_audio_device.h"
30#include "modules/audio_processing/include/mock_audio_processing.h"
31#include "pc/channel.h"
32#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010034#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "test/field_trial.h"
36#include "test/gtest.h"
37#include "test/mock_audio_decoder_factory.h"
38#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039
Elad Alon157540a2019-02-08 23:37:52 +010040using ::testing::_;
41using ::testing::ContainerEq;
42using ::testing::Contains;
43using ::testing::Field;
44using ::testing::Return;
45using ::testing::ReturnPointee;
46using ::testing::SaveArg;
47using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000048
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020049namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010050using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020051
solenberg418b7d32017-06-13 00:38:27 -070052constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070053
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
55const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070056const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070057const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
58const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070059const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
60const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020061const cricket::AudioCodec kTelephoneEventCodec1(106,
62 "telephone-event",
63 8000,
64 0,
65 1);
66const cricket::AudioCodec kTelephoneEventCodec2(107,
67 "telephone-event",
68 32000,
69 0,
70 1);
solenberg2779bab2016-11-17 04:45:19 -080071
solenberg2100c0b2017-03-01 11:29:29 -080072const uint32_t kSsrc0 = 0;
73const uint32_t kSsrc1 = 1;
74const uint32_t kSsrcX = 0x99;
75const uint32_t kSsrcY = 0x17;
76const uint32_t kSsrcZ = 0x42;
77const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020078const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079
solenberg971cab02016-06-14 10:02:41 -070080constexpr int kRtpHistoryMs = 5000;
81
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010082constexpr webrtc::AudioProcessing::Config::GainController1::Mode
83 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010084#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010085 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010086#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010087 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010088#endif
89
90constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
91 webrtc::NoiseSuppression::kHigh;
92
solenberg9a5f032222017-03-15 06:14:12 -070093void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
94 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010095
96 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010097 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010098 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010099 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700100#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200101 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200102 *adm,
103 SetPlayoutDevice(
104 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
105 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200106 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700107#else
108 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
109#endif // #if defined(WEBRTC_WIN)
110 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200111 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700112 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200114 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200115 *adm,
116 SetRecordingDevice(
117 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
118 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200119 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100120#else
121 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
122#endif // #if defined(WEBRTC_WIN)
123 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200124 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
125 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100126 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700127 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
128 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
129 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100130
131 // Teardown.
132 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
133 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
134 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
135 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200136 EXPECT_CALL(*adm, Release())
137 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100138 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700139}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200140} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141
solenbergff976312016-03-30 23:28:51 -0700142// Tests that our stub library "works".
143TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100144 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
145 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700146 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700147 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700148 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
149 new rtc::RefCountedObject<
150 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700151 webrtc::AudioProcessing::Config apm_config;
152 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
153 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200154 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700155 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700156 {
ossuc54071d2016-08-17 02:45:41 -0700157 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100158 task_queue_factory.get(), &adm,
159 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100160 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700161 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700162 }
solenbergff976312016-03-30 23:28:51 -0700163}
164
deadbeef884f5852016-01-15 09:20:04 -0800165class FakeAudioSink : public webrtc::AudioSinkInterface {
166 public:
167 void OnData(const Data& audio) override {}
168};
169
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800170class FakeAudioSource : public cricket::AudioSource {
171 void SetSink(Sink* sink) override {}
172};
173
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200174class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175 public:
stefanba4c0e42016-02-04 04:12:24 -0800176 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
177
178 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100179 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
180 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700181 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700182 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100183 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700184 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800185 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700186 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800187 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700188 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
189 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200190 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700191 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800192 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100193 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800194 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(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(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100201 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
202 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700203 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200204 send_parameters_.codecs.push_back(kPcmuCodec);
205 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100206
solenberg76377c52017-02-21 00:54:31 -0800207 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200208 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800209 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100210 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100211 VerifyGainControlEnabledCorrectly();
212 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 }
solenberg8189b022016-06-14 12:13:00 -0700214
solenbergff976312016-03-30 23:28:51 -0700215 bool SetupChannel() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200216 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100217 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
218 cricket::AudioOptions(),
219 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200220 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000221 }
solenberg8189b022016-06-14 12:13:00 -0700222
solenbergff976312016-03-30 23:28:51 -0700223 bool SetupRecvStream() {
224 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700225 return false;
226 }
solenberg2100c0b2017-03-01 11:29:29 -0800227 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700228 }
solenberg8189b022016-06-14 12:13:00 -0700229
solenbergff976312016-03-30 23:28:51 -0700230 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200231 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
232 }
233
234 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700235 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000236 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 }
Florent Castellidacec712018-05-24 16:24:21 +0200238 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800239 return false;
240 }
peaha9cc40b2017-06-29 08:32:09 -0700241 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800242 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 }
solenberg8189b022016-06-14 12:13:00 -0700244
245 bool AddRecvStream(uint32_t ssrc) {
246 EXPECT_TRUE(channel_);
247 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
248 }
249
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000250 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700251 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700252 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800253 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
254 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700255 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800256 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000257 }
solenberg8189b022016-06-14 12:13:00 -0700258
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700260 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700261 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 }
solenberg8189b022016-06-14 12:13:00 -0700263
Yves Gerey665174f2018-06-19 15:03:05 +0200264 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000265
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100266 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
267 const auto* send_stream = call_.GetAudioSendStream(ssrc);
268 EXPECT_TRUE(send_stream);
269 return *send_stream;
270 }
271
deadbeef884f5852016-01-15 09:20:04 -0800272 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
273 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
274 EXPECT_TRUE(recv_stream);
275 return *recv_stream;
276 }
277
solenberg3a941542015-11-16 07:34:50 -0800278 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800279 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800280 }
281
solenberg7add0582015-11-20 09:59:34 -0800282 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800283 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800284 }
285
solenberg059fb442016-10-26 05:12:24 -0700286 void SetSend(bool enable) {
287 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700288 if (enable) {
289 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
290 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
291 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200292 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700293 }
solenberg059fb442016-10-26 05:12:24 -0700294 channel_->SetSend(enable);
295 }
296
297 void SetSendParameters(const cricket::AudioSendParameters& params) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200298 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenberg059fb442016-10-26 05:12:24 -0700299 ASSERT_TRUE(channel_);
300 EXPECT_TRUE(channel_->SetSendParameters(params));
301 }
302
Yves Gerey665174f2018-06-19 15:03:05 +0200303 void SetAudioSend(uint32_t ssrc,
304 bool enable,
305 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700306 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700307 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700308 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700309 if (enable && options) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200310 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
minyue6b825df2016-10-31 04:08:32 -0700311 }
312 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700313 }
314
Yves Gerey665174f2018-06-19 15:03:05 +0200315 void TestInsertDtmf(uint32_t ssrc,
316 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800317 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700318 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000319 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700320 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200322 EXPECT_TRUE(
323 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000325
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700327 SetSendParameters(send_parameters_);
328 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800330 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800331 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700332 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000334
335 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700336 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800337 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200338 EXPECT_TRUE(
339 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000340 }
341
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800343 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100345 // Test send.
346 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800347 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100348 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800349 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800350 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800351 EXPECT_EQ(codec.id, telephone_event.payload_type);
352 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100353 EXPECT_EQ(2, telephone_event.event_code);
354 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000355 }
356
Johannes Kron9190b822018-10-29 11:22:05 +0100357 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
358 // For a caller, the answer will be applied in set remote description
359 // where SetSendParameters() is called.
360 EXPECT_TRUE(SetupChannel());
361 EXPECT_TRUE(
362 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
363 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
364 SetSendParameters(send_parameters_);
365 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
366 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
367 }
368
369 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
370 // For a callee, the answer will be applied in set local description
371 // where SetExtmapAllowMixed() and AddSendStream() are called.
372 EXPECT_TRUE(SetupChannel());
373 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
374 EXPECT_TRUE(
375 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
376
377 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
378 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
379 }
380
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000381 // Test that send bandwidth is set correctly.
382 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000383 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
384 // |expected_result| is the expected result from SetMaxSendBandwidth().
385 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700386 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
387 int max_bitrate,
388 bool expected_result,
389 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200390 cricket::AudioSendParameters parameters;
391 parameters.codecs.push_back(codec);
392 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700393 if (expected_result) {
394 SetSendParameters(parameters);
395 } else {
396 EXPECT_FALSE(channel_->SetSendParameters(parameters));
397 }
solenberg2100c0b2017-03-01 11:29:29 -0800398 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000399 }
400
skvlade0d46372016-04-07 22:59:22 -0700401 // Sets the per-stream maximum bitrate limit for the specified SSRC.
402 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700403 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700404 EXPECT_EQ(1UL, parameters.encodings.size());
405
Oskar Sundbom78807582017-11-16 11:09:55 +0100406 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800407 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700408 }
409
solenberg059fb442016-10-26 05:12:24 -0700410 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700411 cricket::AudioSendParameters send_parameters;
412 send_parameters.codecs.push_back(codec);
413 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700414 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700415 }
416
ossu20a4b3f2017-04-27 02:08:52 -0700417 void CheckSendCodecBitrate(int32_t ssrc,
418 const char expected_name[],
419 int expected_bitrate) {
420 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
421 EXPECT_EQ(expected_name, spec->format.name);
422 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700423 }
424
Danil Chapovalov00c71832018-06-15 15:58:38 +0200425 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700426 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700427 }
428
Danil Chapovalov00c71832018-06-15 15:58:38 +0200429 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
430 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700431 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
432 }
433
skvlade0d46372016-04-07 22:59:22 -0700434 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
435 int global_max,
436 int stream_max,
437 bool expected_result,
438 int expected_codec_bitrate) {
439 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800440 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700441
442 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700443 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800444 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700445
446 // Verify that reading back the parameters gives results
447 // consistent with the Set() result.
448 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800449 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700450 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
451 EXPECT_EQ(expected_result ? stream_max : -1,
452 resulting_parameters.encodings[0].max_bitrate_bps);
453
454 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800455 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700456 }
457
stefan13f1a0a2016-11-30 07:22:58 -0800458 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
459 int expected_min_bitrate_bps,
460 const char* start_bitrate_kbps,
461 int expected_start_bitrate_bps,
462 const char* max_bitrate_kbps,
463 int expected_max_bitrate_bps) {
464 EXPECT_TRUE(SetupSendStream());
465 auto& codecs = send_parameters_.codecs;
466 codecs.clear();
467 codecs.push_back(kOpusCodec);
468 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
469 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
470 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100471 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
472 SetSdpBitrateParameters(
473 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
474 expected_min_bitrate_bps),
475 Field(&BitrateConstraints::start_bitrate_bps,
476 expected_start_bitrate_bps),
477 Field(&BitrateConstraints::max_bitrate_bps,
478 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800479
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100480 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800481 }
482
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000483 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700484 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000485
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800487 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000488
489 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700490 send_parameters_.extensions.push_back(
491 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700492 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000494
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000495 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200496 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700497 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extension is set properly.
501 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700502 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700503 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
505 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
506 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000507
solenberg7add0582015-11-20 09:59:34 -0800508 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200509 EXPECT_TRUE(
510 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
512 call_.GetAudioSendStream(kSsrcY));
513 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
514 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
515 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000516
517 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200518 send_parameters_.codecs.push_back(kPcmuCodec);
519 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700520 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800521 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
522 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000523 }
524
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000525 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700526 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000527
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000528 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800529 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000530
531 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700532 recv_parameters_.extensions.push_back(
533 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800534 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800535 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000536
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000537 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800538 recv_parameters_.extensions.clear();
539 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800540 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000541
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000542 // Ensure extension is set properly.
543 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700544 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800545 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800546 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
547 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
548 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000549
solenberg7add0582015-11-20 09:59:34 -0800550 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800551 EXPECT_TRUE(AddRecvStream(kSsrcY));
552 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
553 call_.GetAudioReceiveStream(kSsrcY));
554 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
555 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
556 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000557
558 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800559 recv_parameters_.extensions.clear();
560 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800561 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
562 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000563 }
564
solenberg85a04962015-10-27 03:35:21 -0700565 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
566 webrtc::AudioSendStream::Stats stats;
567 stats.local_ssrc = 12;
568 stats.bytes_sent = 345;
569 stats.packets_sent = 678;
570 stats.packets_lost = 9012;
571 stats.fraction_lost = 34.56f;
572 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100573 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700574 stats.ext_seqnum = 789;
575 stats.jitter_ms = 12;
576 stats.rtt_ms = 345;
577 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100578 stats.apm_statistics.delay_median_ms = 234;
579 stats.apm_statistics.delay_standard_deviation_ms = 567;
580 stats.apm_statistics.echo_return_loss = 890;
581 stats.apm_statistics.echo_return_loss_enhancement = 1234;
582 stats.apm_statistics.residual_echo_likelihood = 0.432f;
583 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100584 stats.ana_statistics.bitrate_action_counter = 321;
585 stats.ana_statistics.channel_action_counter = 432;
586 stats.ana_statistics.dtx_action_counter = 543;
587 stats.ana_statistics.fec_action_counter = 654;
588 stats.ana_statistics.frame_length_increase_counter = 765;
589 stats.ana_statistics.frame_length_decrease_counter = 876;
590 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700591 stats.typing_noise_detected = true;
592 return stats;
593 }
594 void SetAudioSendStreamStats() {
595 for (auto* s : call_.GetAudioSendStreams()) {
596 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200597 }
solenberg85a04962015-10-27 03:35:21 -0700598 }
solenberg566ef242015-11-06 15:34:49 -0800599 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
600 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700601 const auto stats = GetAudioSendStreamStats();
602 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
603 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
604 EXPECT_EQ(info.packets_sent, stats.packets_sent);
605 EXPECT_EQ(info.packets_lost, stats.packets_lost);
606 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
607 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800608 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700609 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
610 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
611 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
612 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100613 EXPECT_EQ(info.apm_statistics.delay_median_ms,
614 stats.apm_statistics.delay_median_ms);
615 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
616 stats.apm_statistics.delay_standard_deviation_ms);
617 EXPECT_EQ(info.apm_statistics.echo_return_loss,
618 stats.apm_statistics.echo_return_loss);
619 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
620 stats.apm_statistics.echo_return_loss_enhancement);
621 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
622 stats.apm_statistics.residual_echo_likelihood);
623 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
624 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700625 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
626 stats.ana_statistics.bitrate_action_counter);
627 EXPECT_EQ(info.ana_statistics.channel_action_counter,
628 stats.ana_statistics.channel_action_counter);
629 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
630 stats.ana_statistics.dtx_action_counter);
631 EXPECT_EQ(info.ana_statistics.fec_action_counter,
632 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700633 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
634 stats.ana_statistics.frame_length_increase_counter);
635 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
636 stats.ana_statistics.frame_length_decrease_counter);
637 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
638 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800639 EXPECT_EQ(info.typing_noise_detected,
640 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700641 }
642
643 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
644 webrtc::AudioReceiveStream::Stats stats;
645 stats.remote_ssrc = 123;
646 stats.bytes_rcvd = 456;
647 stats.packets_rcvd = 768;
648 stats.packets_lost = 101;
649 stats.fraction_lost = 23.45f;
650 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100651 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700652 stats.ext_seqnum = 678;
653 stats.jitter_ms = 901;
654 stats.jitter_buffer_ms = 234;
655 stats.jitter_buffer_preferred_ms = 567;
656 stats.delay_estimate_ms = 890;
657 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700658 stats.total_samples_received = 5678901;
659 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200660 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200661 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100662 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.expand_rate = 5.67f;
664 stats.speech_expand_rate = 8.90f;
665 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200666 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700667 stats.accelerate_rate = 4.56f;
668 stats.preemptive_expand_rate = 7.89f;
669 stats.decoding_calls_to_silence_generator = 12;
670 stats.decoding_calls_to_neteq = 345;
671 stats.decoding_normal = 67890;
672 stats.decoding_plc = 1234;
673 stats.decoding_cng = 5678;
674 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700675 stats.decoding_muted_output = 3456;
676 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200677 return stats;
678 }
679 void SetAudioReceiveStreamStats() {
680 for (auto* s : call_.GetAudioReceiveStreams()) {
681 s->SetStats(GetAudioReceiveStreamStats());
682 }
683 }
684 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700685 const auto stats = GetAudioReceiveStreamStats();
686 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
687 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200688 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
689 stats.packets_rcvd);
690 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
691 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700692 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
693 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800694 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
696 stats.ext_seqnum);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
699 stats.jitter_buffer_ms);
700 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700701 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200702 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
703 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700704 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700705 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
706 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200707 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200708 EXPECT_EQ(info.jitter_buffer_delay_seconds,
709 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100710 EXPECT_EQ(info.jitter_buffer_emitted_count,
711 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700712 EXPECT_EQ(info.expand_rate, stats.expand_rate);
713 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
714 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200715 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700716 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
717 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200718 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700719 stats.decoding_calls_to_silence_generator);
720 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
721 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
722 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
723 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
724 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700725 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700726 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200727 }
hbos1acfbd22016-11-17 23:43:29 -0800728 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
729 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
730 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
731 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
732 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
733 codec.ToCodecParameters());
734 }
735 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
736 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
737 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
738 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
739 codec.ToCodecParameters());
740 }
741 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200742
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100743 void VerifyGainControlEnabledCorrectly() {
744 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
745 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
746 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
747 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
748 }
749
750 void VerifyGainControlDefaultSettings() {
751 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
752 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
753 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
754 }
755
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200756 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100757 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200758 }
759
peah8271d042016-11-22 07:24:52 -0800760 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100761 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800762 }
763
Sam Zackrissonba502232019-01-04 10:36:48 +0100764 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100765 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100766 }
767
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100769 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700770 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700771 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800772 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200773 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700774 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700775 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200776 cricket::AudioSendParameters send_parameters_;
777 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800778 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700779 webrtc::AudioProcessing::Config apm_config_;
780
stefanba4c0e42016-02-04 04:12:24 -0800781 private:
782 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783};
784
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100786TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700787 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788}
789
solenberg31fec402016-05-06 02:13:12 -0700790// Test that we can add a send stream and that it has the correct defaults.
791TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
792 EXPECT_TRUE(SetupChannel());
793 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800794 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
795 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
796 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700797 EXPECT_EQ("", config.rtp.c_name);
798 EXPECT_EQ(0u, config.rtp.extensions.size());
799 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
800 config.send_transport);
801}
802
803// Test that we can add a receive stream and that it has the correct defaults.
804TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
805 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800806 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700807 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800808 GetRecvStreamConfig(kSsrcX);
809 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700810 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
811 EXPECT_FALSE(config.rtp.transport_cc);
812 EXPECT_EQ(0u, config.rtp.extensions.size());
813 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
814 config.rtcp_send_transport);
815 EXPECT_EQ("", config.sync_group);
816}
817
stefanba4c0e42016-02-04 04:12:24 -0800818TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700819 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800820 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100821 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800822 if (codec.name == "opus") {
823 EXPECT_TRUE(HasTransportCc(codec));
824 opus_found = true;
825 }
826 }
827 EXPECT_TRUE(opus_found);
828}
829
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830// Test that we set our inbound codecs properly, including changing PT.
831TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700832 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200833 cricket::AudioRecvParameters parameters;
834 parameters.codecs.push_back(kIsacCodec);
835 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800836 parameters.codecs.push_back(kTelephoneEventCodec1);
837 parameters.codecs.push_back(kTelephoneEventCodec2);
838 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200839 parameters.codecs[2].id = 126;
840 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800841 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700842 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
843 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
844 {{0, {"PCMU", 8000, 1}},
845 {106, {"ISAC", 16000, 1}},
846 {126, {"telephone-event", 8000, 1}},
847 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848}
849
850// Test that we fail to set an unknown inbound codec.
851TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700852 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200853 cricket::AudioRecvParameters parameters;
854 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700855 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
859// Test that we fail if we have duplicate types in the inbound list.
860TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700861 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200862 cricket::AudioRecvParameters parameters;
863 parameters.codecs.push_back(kIsacCodec);
864 parameters.codecs.push_back(kCn16000Codec);
865 parameters.codecs[1].id = kIsacCodec.id;
866 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867}
868
869// Test that we can decode OPUS without stereo parameters.
870TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
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 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800877 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700878 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
879 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
880 {{0, {"PCMU", 8000, 1}},
881 {103, {"ISAC", 16000, 1}},
882 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883}
884
885// Test that we can decode OPUS with stereo = 0.
886TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700887 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200888 cricket::AudioRecvParameters parameters;
889 parameters.codecs.push_back(kIsacCodec);
890 parameters.codecs.push_back(kPcmuCodec);
891 parameters.codecs.push_back(kOpusCodec);
892 parameters.codecs[2].params["stereo"] = "0";
893 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800894 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700895 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
896 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
897 {{0, {"PCMU", 8000, 1}},
898 {103, {"ISAC", 16000, 1}},
899 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900}
901
902// Test that we can decode OPUS with stereo = 1.
903TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700904 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200905 cricket::AudioRecvParameters parameters;
906 parameters.codecs.push_back(kIsacCodec);
907 parameters.codecs.push_back(kPcmuCodec);
908 parameters.codecs.push_back(kOpusCodec);
909 parameters.codecs[2].params["stereo"] = "1";
910 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800911 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700912 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
913 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
914 {{0, {"PCMU", 8000, 1}},
915 {103, {"ISAC", 16000, 1}},
916 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917}
918
919// Test that changes to recv codecs are applied to all streams.
920TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700921 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 cricket::AudioRecvParameters parameters;
923 parameters.codecs.push_back(kIsacCodec);
924 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800925 parameters.codecs.push_back(kTelephoneEventCodec1);
926 parameters.codecs.push_back(kTelephoneEventCodec2);
927 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200928 parameters.codecs[2].id = 126;
929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700930 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
931 EXPECT_TRUE(AddRecvStream(ssrc));
932 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
933 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
934 {{0, {"PCMU", 8000, 1}},
935 {106, {"ISAC", 16000, 1}},
936 {126, {"telephone-event", 8000, 1}},
937 {107, {"telephone-event", 32000, 1}}})));
938 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939}
940
941TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700942 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200943 cricket::AudioRecvParameters parameters;
944 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800945 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200946 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947
solenberg2100c0b2017-03-01 11:29:29 -0800948 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200949 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800950 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951}
952
953// Test that we can apply the same set of codecs again while playing.
954TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200956 cricket::AudioRecvParameters parameters;
957 parameters.codecs.push_back(kIsacCodec);
958 parameters.codecs.push_back(kCn16000Codec);
959 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700960 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200961 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
deadbeefcb383672017-04-26 16:28:42 -0700963 // Remapping a payload type to a different codec should fail.
964 parameters.codecs[0] = kOpusCodec;
965 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200966 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800967 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
970// Test that we can add a codec while playing.
971TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700972 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200973 cricket::AudioRecvParameters parameters;
974 parameters.codecs.push_back(kIsacCodec);
975 parameters.codecs.push_back(kCn16000Codec);
976 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700977 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200979 parameters.codecs.push_back(kOpusCodec);
980 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800981 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982}
983
deadbeefcb383672017-04-26 16:28:42 -0700984// Test that we accept adding the same codec with a different payload type.
985// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
986TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
987 EXPECT_TRUE(SetupRecvStream());
988 cricket::AudioRecvParameters parameters;
989 parameters.codecs.push_back(kIsacCodec);
990 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
991
992 ++parameters.codecs[0].id;
993 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
994}
995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700997 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999 // Test that when autobw is enabled, bitrate is kept as the default
1000 // value. autobw is enabled for the following tests because the target
1001 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002
1003 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001004 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005
1006 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001007 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001008
ossu20a4b3f2017-04-27 02:08:52 -07001009 // opus, default bitrate == 32000 in mono.
1010 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011}
1012
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001013TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001014 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001017 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1018 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001019 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001022 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1023 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1024 // Rates above the max (510000) should be capped.
1025 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001026}
1027
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001028TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001029 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001030
1031 // Test that we can only set a maximum bitrate for a fixed-rate codec
1032 // if it's bigger than the fixed rate.
1033
1034 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001035 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1041 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001042}
1043
1044TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001045 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001046 const int kDesiredBitrate = 128000;
1047 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001048 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001049 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001050 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001051
Yves Gerey665174f2018-06-19 15:03:05 +02001052 EXPECT_TRUE(
1053 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001054
solenberg2100c0b2017-03-01 11:29:29 -08001055 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001056}
1057
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001058// Test that bitrate cannot be set for CBR codecs.
1059// Bitrate is ignored if it is higher than the fixed bitrate.
1060// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001061TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001062 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063
1064 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001065 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001067
1068 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001069 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001071
1072 send_parameters_.max_bandwidth_bps = 128;
1073 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001074 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001075}
1076
skvlade0d46372016-04-07 22:59:22 -07001077// Test that the per-stream bitrate limit and the global
1078// bitrate limit both apply.
1079TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1080 EXPECT_TRUE(SetupSendStream());
1081
ossu20a4b3f2017-04-27 02:08:52 -07001082 // opus, default bitrate == 32000.
1083 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001084 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1085 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1086 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1087
1088 // CBR codecs allow both maximums to exceed the bitrate.
1089 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1090 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1093
1094 // CBR codecs don't allow per stream maximums to be too low.
1095 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1096 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1097}
1098
1099// Test that an attempt to set RtpParameters for a stream that does not exist
1100// fails.
1101TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1102 EXPECT_TRUE(SetupChannel());
1103 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001104 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001105 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001106
1107 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001108 EXPECT_FALSE(
1109 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001110}
1111
1112TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001113 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001114 // This test verifies that setting RtpParameters succeeds only if
1115 // the structure contains exactly one encoding.
1116 // TODO(skvlad): Update this test when we start supporting setting parameters
1117 // for each encoding individually.
1118
1119 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001120 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001121 // Two or more encodings should result in failure.
1122 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001123 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001124 // Zero encodings should also fail.
1125 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001126 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001127}
1128
1129// Changing the SSRC through RtpParameters is not allowed.
1130TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1131 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001132 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001133 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001134 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001135}
1136
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001137// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001138// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1140 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001141 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001142 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001143 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001144 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001145 ASSERT_EQ(1u, parameters.encodings.size());
1146 ASSERT_TRUE(parameters.encodings[0].active);
1147 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001148 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001149 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001150
1151 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001152 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001153 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001154 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001155 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001156 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001157}
1158
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001159// Test that SetRtpSendParameters configures the correct encoding channel for
1160// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001161TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1162 SetupForMultiSendStream();
1163 // Create send streams.
1164 for (uint32_t ssrc : kSsrcs4) {
1165 EXPECT_TRUE(
1166 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1167 }
1168 // Configure one stream to be limited by the stream config, another to be
1169 // limited by the global max, and the third one with no per-stream limit
1170 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001171 SetGlobalMaxBitrate(kOpusCodec, 32000);
1172 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001174 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1175
ossu20a4b3f2017-04-27 02:08:52 -07001176 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1177 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1178 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001179
1180 // Remove the global cap; the streams should switch to their respective
1181 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001182 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001183 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1184 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1185 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001186}
1187
Tim Haloun648d28a2018-10-18 16:52:22 -07001188// RTCRtpEncodingParameters.network_priority must be one of a few values
1189// derived from the default priority, corresponding to very-low, low, medium,
1190// or high.
1191TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1192 EXPECT_TRUE(SetupSendStream());
1193 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1194 EXPECT_EQ(1UL, parameters.encodings.size());
1195 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1196 parameters.encodings[0].network_priority);
1197
1198 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1199 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1200 for (auto it : good_values) {
1201 parameters.encodings[0].network_priority = it;
1202 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1203 }
1204 for (auto it : bad_values) {
1205 parameters.encodings[0].network_priority = it;
1206 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1207 }
1208}
1209
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210// Test that GetRtpSendParameters returns the currently configured codecs.
1211TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001212 EXPECT_TRUE(SetupSendStream());
1213 cricket::AudioSendParameters parameters;
1214 parameters.codecs.push_back(kIsacCodec);
1215 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001216 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001217
solenberg2100c0b2017-03-01 11:29:29 -08001218 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001219 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001220 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1221 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001222}
1223
Florent Castellidacec712018-05-24 16:24:21 +02001224// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1225TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1226 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1227 params.cname = "rtcpcname";
1228 EXPECT_TRUE(SetupSendStream(params));
1229
1230 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1231 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1232}
1233
Florent Castelliabe301f2018-06-12 18:33:49 +02001234TEST_F(WebRtcVoiceEngineTestFake,
1235 DetectRtpSendParameterHeaderExtensionsChange) {
1236 EXPECT_TRUE(SetupSendStream());
1237
1238 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1239 rtp_parameters.header_extensions.emplace_back();
1240
1241 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1242
1243 webrtc::RTCError result =
1244 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1245 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1246}
1247
deadbeefcb443432016-12-12 11:12:36 -08001248// Test that GetRtpSendParameters returns an SSRC.
1249TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1250 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001251 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001252 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001253 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001254}
1255
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001256// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001257TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001258 EXPECT_TRUE(SetupSendStream());
1259 cricket::AudioSendParameters parameters;
1260 parameters.codecs.push_back(kIsacCodec);
1261 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001262 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001263
solenberg2100c0b2017-03-01 11:29:29 -08001264 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001265
1266 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001267 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001268
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001269 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001270 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1271 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001272}
1273
minyuececec102017-03-27 13:04:25 -07001274// Test that max_bitrate_bps in send stream config gets updated correctly when
1275// SetRtpSendParameters is called.
1276TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1277 webrtc::test::ScopedFieldTrials override_field_trials(
1278 "WebRTC-Audio-SendSideBwe/Enabled/");
1279 EXPECT_TRUE(SetupSendStream());
1280 cricket::AudioSendParameters send_parameters;
1281 send_parameters.codecs.push_back(kOpusCodec);
1282 SetSendParameters(send_parameters);
1283
1284 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1285 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1286 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1287
1288 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001289 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001290 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001291
1292 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1293 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1294}
1295
Seth Hampson24722b32017-12-22 09:36:42 -08001296// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1297// a value <= 0, setting the parameters returns false.
1298TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1299 EXPECT_TRUE(SetupSendStream());
1300 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1301 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1302 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1303 rtp_parameters.encodings[0].bitrate_priority);
1304
1305 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001306 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001307 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001308 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001309}
1310
1311// Test that the bitrate_priority in the send stream config gets updated when
1312// SetRtpSendParameters is set for the VoiceMediaChannel.
1313TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1314 EXPECT_TRUE(SetupSendStream());
1315 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1316
1317 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1318 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1319 rtp_parameters.encodings[0].bitrate_priority);
1320 double new_bitrate_priority = 2.0;
1321 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001322 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001323
1324 // The priority should get set for both the audio channel's rtp parameters
1325 // and the audio send stream's audio config.
1326 EXPECT_EQ(
1327 new_bitrate_priority,
1328 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1329 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1330}
1331
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001332// Test that GetRtpReceiveParameters returns the currently configured codecs.
1333TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1334 EXPECT_TRUE(SetupRecvStream());
1335 cricket::AudioRecvParameters parameters;
1336 parameters.codecs.push_back(kIsacCodec);
1337 parameters.codecs.push_back(kPcmuCodec);
1338 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1339
1340 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001341 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001342 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1343 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1344 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1345}
1346
deadbeefcb443432016-12-12 11:12:36 -08001347// Test that GetRtpReceiveParameters returns an SSRC.
1348TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1349 EXPECT_TRUE(SetupRecvStream());
1350 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001351 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001352 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001353 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001354}
1355
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001356// Test that if we set/get parameters multiple times, we get the same results.
1357TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1358 EXPECT_TRUE(SetupRecvStream());
1359 cricket::AudioRecvParameters parameters;
1360 parameters.codecs.push_back(kIsacCodec);
1361 parameters.codecs.push_back(kPcmuCodec);
1362 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1363
1364 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001365 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001366
1367 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001368 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001369
1370 // ... And this shouldn't change the params returned by
1371 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001372 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1373 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001374}
1375
deadbeef3bc15102017-04-20 19:25:07 -07001376// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1377// aren't signaled. It should return an empty "RtpEncodingParameters" when
1378// configured to receive an unsignaled stream and no packets have been received
1379// yet, and start returning the SSRC once a packet has been received.
1380TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1381 ASSERT_TRUE(SetupChannel());
1382 // Call necessary methods to configure receiving a default stream as
1383 // soon as it arrives.
1384 cricket::AudioRecvParameters parameters;
1385 parameters.codecs.push_back(kIsacCodec);
1386 parameters.codecs.push_back(kPcmuCodec);
1387 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1388
1389 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1390 // stream. Should return nothing.
1391 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1392
1393 // Set a sink for an unsignaled stream.
1394 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1395 // Value of "0" means "unsignaled stream".
1396 channel_->SetRawAudioSink(0, std::move(fake_sink));
1397
1398 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1399 // in this method means "unsignaled stream".
1400 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1401 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1402 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1403
1404 // Receive PCMU packet (SSRC=1).
1405 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1406
1407 // The |ssrc| member should still be unset.
1408 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1409 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1410 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1411}
1412
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413// Test that we apply codecs properly.
1414TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001415 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kIsacCodec);
1418 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001419 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001421 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001422 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001423 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1424 EXPECT_EQ(96, send_codec_spec.payload_type);
1425 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1426 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1427 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001428 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001429 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001430}
1431
ossu20a4b3f2017-04-27 02:08:52 -07001432// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1433// AudioSendStream.
1434TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kIsacCodec);
1438 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001439 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 parameters.codecs[0].id = 96;
1441 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001442 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001444 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001445 // Calling SetSendCodec again with same codec which is already set.
1446 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001447 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001448 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001449}
1450
ossu20a4b3f2017-04-27 02:08:52 -07001451// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1452// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001453
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001454// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 0;
1460 parameters.codecs[0].clockrate = 50000;
1461 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462}
1463
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001464// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001466 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 cricket::AudioSendParameters parameters;
1468 parameters.codecs.push_back(kOpusCodec);
1469 parameters.codecs[0].bitrate = 0;
1470 parameters.codecs[0].channels = 0;
1471 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472}
1473
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001474// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001476 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 cricket::AudioSendParameters parameters;
1478 parameters.codecs.push_back(kOpusCodec);
1479 parameters.codecs[0].bitrate = 0;
1480 parameters.codecs[0].channels = 0;
1481 parameters.codecs[0].params["stereo"] = "1";
1482 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001483}
1484
1485// Test that if channel is 1 for opus and there's no stereo, we fail.
1486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001487 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001488 cricket::AudioSendParameters parameters;
1489 parameters.codecs.push_back(kOpusCodec);
1490 parameters.codecs[0].bitrate = 0;
1491 parameters.codecs[0].channels = 1;
1492 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
1495// Test that if channel is 1 for opus and stereo=0, we fail.
1496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001497 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 cricket::AudioSendParameters parameters;
1499 parameters.codecs.push_back(kOpusCodec);
1500 parameters.codecs[0].bitrate = 0;
1501 parameters.codecs[0].channels = 1;
1502 parameters.codecs[0].params["stereo"] = "0";
1503 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001504}
1505
1506// Test that if channel is 1 for opus and stereo=1, we fail.
1507TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001508 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001509 cricket::AudioSendParameters parameters;
1510 parameters.codecs.push_back(kOpusCodec);
1511 parameters.codecs[0].bitrate = 0;
1512 parameters.codecs[0].channels = 1;
1513 parameters.codecs[0].params["stereo"] = "1";
1514 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001515}
1516
ossu20a4b3f2017-04-27 02:08:52 -07001517// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001518TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001519 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001520 cricket::AudioSendParameters parameters;
1521 parameters.codecs.push_back(kOpusCodec);
1522 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001524 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001525}
1526
ossu20a4b3f2017-04-27 02:08:52 -07001527// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001529 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001530 cricket::AudioSendParameters parameters;
1531 parameters.codecs.push_back(kOpusCodec);
1532 parameters.codecs[0].bitrate = 0;
1533 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001534 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001535 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001536}
1537
ossu20a4b3f2017-04-27 02:08:52 -07001538// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001539TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
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].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001544 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001546 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001547 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001548
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001549 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001550 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001551 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001552}
1553
ossu20a4b3f2017-04-27 02:08:52 -07001554// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001555TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001556 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001557 cricket::AudioSendParameters parameters;
1558 parameters.codecs.push_back(kOpusCodec);
1559 parameters.codecs[0].bitrate = 0;
1560 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001561 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001562 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563}
1564
ossu20a4b3f2017-04-27 02:08:52 -07001565// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001566TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
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].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001571 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001572 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001574 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001575
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001576 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001577 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001578 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001579}
1580
ossu20a4b3f2017-04-27 02:08:52 -07001581// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001583 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001584 cricket::AudioSendParameters parameters;
1585 parameters.codecs.push_back(kOpusCodec);
1586 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001587 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001588 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1589 EXPECT_EQ(111, spec.payload_type);
1590 EXPECT_EQ(96000, spec.target_bitrate_bps);
1591 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001592 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001593 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001594}
1595
ossu20a4b3f2017-04-27 02:08:52 -07001596// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001598 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 cricket::AudioSendParameters parameters;
1600 parameters.codecs.push_back(kOpusCodec);
1601 parameters.codecs[0].bitrate = 30000;
1602 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001604 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001605}
1606
ossu20a4b3f2017-04-27 02:08:52 -07001607// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001609 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001610 cricket::AudioSendParameters parameters;
1611 parameters.codecs.push_back(kOpusCodec);
1612 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001613 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001614 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001615}
1616
ossu20a4b3f2017-04-27 02:08:52 -07001617// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001619 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001620 cricket::AudioSendParameters parameters;
1621 parameters.codecs.push_back(kOpusCodec);
1622 parameters.codecs[0].bitrate = 30000;
1623 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001625 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001626}
1627
stefan13f1a0a2016-11-30 07:22:58 -08001628TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1629 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1630 200000);
1631}
1632
1633TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1634 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1635}
1636
1637TEST_F(WebRtcVoiceEngineTestFake,
1638 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1639 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1640}
1641
1642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1643 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1644}
1645
Yves Gerey665174f2018-06-19 15:03:05 +02001646TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001647 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1648 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001649 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001650 // Setting max bitrate should keep previous min bitrate
1651 // Setting max bitrate should not reset start bitrate.
1652 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1653 SetSdpBitrateParameters(
1654 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1655 Field(&BitrateConstraints::start_bitrate_bps, -1),
1656 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001657 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001658}
1659
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001660// Test that we can enable NACK with opus as callee.
1661TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001662 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001663 cricket::AudioSendParameters parameters;
1664 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001665 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1666 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001667 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001668 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001669 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001670 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001671
Yves Gerey665174f2018-06-19 15:03:05 +02001672 EXPECT_TRUE(
1673 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001674}
1675
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001676// Test that we can enable NACK on receive streams.
1677TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001678 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001679 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 cricket::AudioSendParameters parameters;
1681 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001682 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1683 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001684 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001685 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001686 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001687}
1688
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689// Test that we can disable NACK on receive streams.
1690TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001691 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001692 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 cricket::AudioSendParameters parameters;
1694 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001695 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1696 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001697 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001698 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001699
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 parameters.codecs.clear();
1701 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001703 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001704}
1705
1706// Test that NACK is enabled on a new receive stream.
1707TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001708 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 cricket::AudioSendParameters parameters;
1710 parameters.codecs.push_back(kIsacCodec);
1711 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001712 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1713 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715
solenberg2100c0b2017-03-01 11:29:29 -08001716 EXPECT_TRUE(AddRecvStream(kSsrcY));
1717 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1718 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1719 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720}
1721
stefanba4c0e42016-02-04 04:12:24 -08001722TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001723 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001724 cricket::AudioSendParameters send_parameters;
1725 send_parameters.codecs.push_back(kOpusCodec);
1726 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001728
1729 cricket::AudioRecvParameters recv_parameters;
1730 recv_parameters.codecs.push_back(kIsacCodec);
1731 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001732 EXPECT_TRUE(AddRecvStream(kSsrcX));
1733 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001734 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001735 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001736
ossudedfd282016-06-14 07:12:39 -07001737 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001739 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001740 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001741 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001742}
1743
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001744// Test that we can switch back and forth between Opus and ISAC with CN.
1745TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001746 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001747
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 cricket::AudioSendParameters opus_parameters;
1749 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001751 {
ossu20a4b3f2017-04-27 02:08:52 -07001752 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1753 EXPECT_EQ(111, spec.payload_type);
1754 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001755 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters isac_parameters;
1758 isac_parameters.codecs.push_back(kIsacCodec);
1759 isac_parameters.codecs.push_back(kCn16000Codec);
1760 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001761 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001762 {
ossu20a4b3f2017-04-27 02:08:52 -07001763 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1764 EXPECT_EQ(103, spec.payload_type);
1765 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001766 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001767
solenberg059fb442016-10-26 05:12:24 -07001768 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001769 {
ossu20a4b3f2017-04-27 02:08:52 -07001770 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1771 EXPECT_EQ(111, spec.payload_type);
1772 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001773 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774}
1775
1776// Test that we handle various ways of specifying bitrate.
1777TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001778 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 cricket::AudioSendParameters parameters;
1780 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001782 {
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(103, spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1786 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001787 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001788
Yves Gerey665174f2018-06-19 15:03:05 +02001789 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001790 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001791 {
ossu20a4b3f2017-04-27 02:08:52 -07001792 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1793 EXPECT_EQ(103, spec.payload_type);
1794 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1795 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001796 }
Yves Gerey665174f2018-06-19 15:03:05 +02001797 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001799 {
ossu20a4b3f2017-04-27 02:08:52 -07001800 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1801 EXPECT_EQ(103, spec.payload_type);
1802 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1803 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001804 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805
Yves Gerey665174f2018-06-19 15:03:05 +02001806 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001808 {
ossu20a4b3f2017-04-27 02:08:52 -07001809 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1810 EXPECT_EQ(0, spec.payload_type);
1811 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1812 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001813 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814
Yves Gerey665174f2018-06-19 15:03:05 +02001815 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001817 {
ossu20a4b3f2017-04-27 02:08:52 -07001818 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1819 EXPECT_EQ(0, spec.payload_type);
1820 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1821 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001822 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001823
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001825 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001827 {
ossu20a4b3f2017-04-27 02:08:52 -07001828 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1829 EXPECT_EQ(111, spec.payload_type);
1830 EXPECT_STREQ("opus", spec.format.name.c_str());
1831 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001832 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001833}
1834
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001835// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001836TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001837 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 cricket::AudioSendParameters parameters;
1839 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001840}
1841
1842// Test that we can set send codecs even with telephone-event codec as the first
1843// one on the list.
1844TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001845 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001846 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001847 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 parameters.codecs.push_back(kIsacCodec);
1849 parameters.codecs.push_back(kPcmuCodec);
1850 parameters.codecs[0].id = 98; // DTMF
1851 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001852 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001853 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1854 EXPECT_EQ(96, spec.payload_type);
1855 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001856 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001857 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001858}
1859
Harald Alvestranda1f66612018-02-21 11:24:23 +01001860// Test that CanInsertDtmf() is governed by the send flag
1861TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1862 EXPECT_TRUE(SetupSendStream());
1863 cricket::AudioSendParameters parameters;
1864 parameters.codecs.push_back(kTelephoneEventCodec1);
1865 parameters.codecs.push_back(kPcmuCodec);
1866 parameters.codecs[0].id = 98; // DTMF
1867 parameters.codecs[1].id = 96;
1868 SetSendParameters(parameters);
1869 EXPECT_FALSE(channel_->CanInsertDtmf());
1870 SetSend(true);
1871 EXPECT_TRUE(channel_->CanInsertDtmf());
1872 SetSend(false);
1873 EXPECT_FALSE(channel_->CanInsertDtmf());
1874}
1875
solenberg31642aa2016-03-14 08:00:37 -07001876// Test that payload type range is limited for telephone-event codec.
1877TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001878 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001879 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001880 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001881 parameters.codecs.push_back(kIsacCodec);
1882 parameters.codecs[0].id = 0; // DTMF
1883 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001884 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001885 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001886 EXPECT_TRUE(channel_->CanInsertDtmf());
1887 parameters.codecs[0].id = 128; // DTMF
1888 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1889 EXPECT_FALSE(channel_->CanInsertDtmf());
1890 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001892 EXPECT_TRUE(channel_->CanInsertDtmf());
1893 parameters.codecs[0].id = -1; // DTMF
1894 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1895 EXPECT_FALSE(channel_->CanInsertDtmf());
1896}
1897
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001898// Test that we can set send codecs even with CN codec as the first
1899// one on the list.
1900TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
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(kCn16000Codec);
1904 parameters.codecs.push_back(kIsacCodec);
1905 parameters.codecs.push_back(kPcmuCodec);
1906 parameters.codecs[0].id = 98; // wideband CN
1907 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001908 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001909 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1910 EXPECT_EQ(96, send_codec_spec.payload_type);
1911 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001912 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001913}
1914
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001915// Test that we set VAD and DTMF types correctly as caller.
1916TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001917 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 cricket::AudioSendParameters parameters;
1919 parameters.codecs.push_back(kIsacCodec);
1920 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001921 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001922 parameters.codecs.push_back(kCn16000Codec);
1923 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001924 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001925 parameters.codecs[0].id = 96;
1926 parameters.codecs[2].id = 97; // wideband CN
1927 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001928 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001929 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1930 EXPECT_EQ(96, send_codec_spec.payload_type);
1931 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001932 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001933 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001934 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001935 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001936}
1937
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001938// Test that we set VAD and DTMF types correctly as callee.
1939TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001940 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 cricket::AudioSendParameters parameters;
1942 parameters.codecs.push_back(kIsacCodec);
1943 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001944 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001945 parameters.codecs.push_back(kCn16000Codec);
1946 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001947 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001948 parameters.codecs[0].id = 96;
1949 parameters.codecs[2].id = 97; // wideband CN
1950 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001952 EXPECT_TRUE(
1953 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001954
ossu20a4b3f2017-04-27 02:08:52 -07001955 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1956 EXPECT_EQ(96, send_codec_spec.payload_type);
1957 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001958 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001959 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001960 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001961 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001962}
1963
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001964// Test that we only apply VAD if we have a CN codec that matches the
1965// send codec clockrate.
1966TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001967 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001968 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 parameters.codecs.push_back(kIsacCodec);
1971 parameters.codecs.push_back(kCn16000Codec);
1972 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001974 {
ossu20a4b3f2017-04-27 02:08:52 -07001975 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1976 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001977 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001978 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001979 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001980 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001981 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001983 {
ossu20a4b3f2017-04-27 02:08:52 -07001984 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1985 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001986 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001987 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001989 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001990 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001991 {
ossu20a4b3f2017-04-27 02:08:52 -07001992 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1993 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001994 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001995 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001996 }
Brave Yao5225dd82015-03-26 07:39:19 +08001997 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001998 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001999 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002000 {
ossu20a4b3f2017-04-27 02:08:52 -07002001 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2002 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002003 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002004 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002005}
2006
2007// Test that we perform case-insensitive matching of codec names.
2008TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002009 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 cricket::AudioSendParameters parameters;
2011 parameters.codecs.push_back(kIsacCodec);
2012 parameters.codecs.push_back(kPcmuCodec);
2013 parameters.codecs.push_back(kCn16000Codec);
2014 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002015 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002016 parameters.codecs[0].name = "iSaC";
2017 parameters.codecs[0].id = 96;
2018 parameters.codecs[2].id = 97; // wideband CN
2019 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002020 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002021 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2022 EXPECT_EQ(96, send_codec_spec.payload_type);
2023 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002024 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002025 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002026 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002027 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002028}
2029
stefanba4c0e42016-02-04 04:12:24 -08002030class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2031 public:
2032 WebRtcVoiceEngineWithSendSideBweTest()
2033 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2034};
2035
2036TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2037 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002038 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2039 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002040 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002041 "uri", &RtpExtension::uri,
2042 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002043}
2044
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002045// Test support for audio level header extension.
2046TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002047 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002048}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002049TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002050 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002051}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002052
solenbergd4adce42016-11-17 06:26:52 -08002053// Test support for transport sequence number header extension.
2054TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2055 TestSetSendRtpHeaderExtensions(
2056 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002057}
solenbergd4adce42016-11-17 06:26:52 -08002058TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2059 TestSetRecvRtpHeaderExtensions(
2060 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002061}
2062
solenberg1ac56142015-10-13 03:58:19 -07002063// Test that we can create a channel and start sending on it.
2064TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002065 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002066 SetSendParameters(send_parameters_);
2067 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002068 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002069 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002070 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002071}
2072
2073// Test that a channel will send if and only if it has a source and is enabled
2074// for sending.
2075TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002076 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002077 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002078 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002079 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002080 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2081 SetAudioSend(kSsrcX, true, &fake_source_);
2082 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2083 SetAudioSend(kSsrcX, true, nullptr);
2084 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002085}
2086
solenberg94218532016-06-16 10:53:22 -07002087// Test that a channel is muted/unmuted.
2088TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2089 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002090 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002091 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2092 SetAudioSend(kSsrcX, true, nullptr);
2093 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2094 SetAudioSend(kSsrcX, false, nullptr);
2095 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002096}
2097
solenberg6d6e7c52016-04-13 09:07:30 -07002098// Test that SetSendParameters() does not alter a stream's send state.
2099TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2100 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002101 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002102
2103 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002104 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002105 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002106
2107 // Changing RTP header extensions will recreate the AudioSendStream.
2108 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002109 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002110 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002112
2113 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002114 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002115 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002116
2117 // Changing RTP header extensions will recreate the AudioSendStream.
2118 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002120 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002121}
2122
solenberg1ac56142015-10-13 03:58:19 -07002123// Test that we can create a channel and start playing out on it.
2124TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002125 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002126 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002127 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002128 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002129 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002131}
2132
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133// Test that we can add and remove send streams.
2134TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2135 SetupForMultiSendStream();
2136
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002138 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139
solenbergc96df772015-10-21 13:01:53 -07002140 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002141 EXPECT_TRUE(
2142 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002143 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002145 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 }
tfarina5237aaf2015-11-10 23:44:30 -08002147 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148
solenbergc96df772015-10-21 13:01:53 -07002149 // Delete the send streams.
2150 for (uint32_t ssrc : kSsrcs4) {
2151 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002152 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002153 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 }
solenbergc96df772015-10-21 13:01:53 -07002155 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156}
2157
2158// Test SetSendCodecs correctly configure the codecs in all send streams.
2159TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2160 SetupForMultiSendStream();
2161
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002163 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002164 EXPECT_TRUE(
2165 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002166 }
2167
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002168 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002169 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002170 parameters.codecs.push_back(kIsacCodec);
2171 parameters.codecs.push_back(kCn16000Codec);
2172 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002173 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002174
2175 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002176 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002177 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2178 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002179 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2180 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002181 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002182 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184
minyue7a973442016-10-20 03:27:12 -07002185 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002186 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002187 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002188 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002189 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2190 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002191 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2192 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002193 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002194 }
2195}
2196
2197// Test we can SetSend on all send streams correctly.
2198TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2199 SetupForMultiSendStream();
2200
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002201 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002202 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002203 EXPECT_TRUE(
2204 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002205 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002206 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207 }
2208
2209 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002210 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002211 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002213 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002214 }
2215
2216 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002217 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002218 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002219 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002220 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 }
2222}
2223
2224// Test we can set the correct statistics on all send streams.
2225TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2226 SetupForMultiSendStream();
2227
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002229 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002230 EXPECT_TRUE(
2231 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002232 }
solenberg85a04962015-10-27 03:35:21 -07002233
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002234 // Create a receive stream to check that none of the send streams end up in
2235 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002236 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002237
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002238 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002239 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002240 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002241 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002242
solenberg85a04962015-10-27 03:35:21 -07002243 // Check stats for the added streams.
2244 {
2245 cricket::VoiceMediaInfo info;
2246 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002247
solenberg85a04962015-10-27 03:35:21 -07002248 // We have added 4 send streams. We should see empty stats for all.
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 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002251 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002252 }
hbos1acfbd22016-11-17 23:43:29 -08002253 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002254
2255 // We have added one receive stream. We should see empty stats.
2256 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002257 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002258 }
solenberg1ac56142015-10-13 03:58:19 -07002259
solenberg2100c0b2017-03-01 11:29:29 -08002260 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002261 {
2262 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002263 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002264 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002265 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002266 EXPECT_EQ(0u, info.receivers.size());
2267 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002268
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002269 // Deliver a new packet - a default receive stream should be created and we
2270 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002271 {
2272 cricket::VoiceMediaInfo info;
2273 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2274 SetAudioReceiveStreamStats();
2275 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002276 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002277 EXPECT_EQ(1u, info.receivers.size());
2278 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002279 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002280 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002281}
2282
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002283// Test that we can add and remove receive streams, and do proper send/playout.
2284// We can receive on multiple streams while sending one stream.
2285TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002286 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
solenberg1ac56142015-10-13 03:58:19 -07002288 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002289 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002290 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291
solenberg1ac56142015-10-13 03:58:19 -07002292 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002293 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002294 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002295 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002296
solenberg1ac56142015-10-13 03:58:19 -07002297 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002298 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002299
2300 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002301 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2302 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2303 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304
2305 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002306 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002307 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002308
2309 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002310 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002311 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2312 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002313
aleloi84ef6152016-08-04 05:28:21 -07002314 // Restart playout and make sure recv streams are played out.
2315 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2317 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002318
aleloi84ef6152016-08-04 05:28:21 -07002319 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002320 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2321 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002322}
2323
wu@webrtc.org97077a32013-10-25 21:18:33 +00002324TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002325 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002326 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002327 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002328 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002329 const auto& agc_config = apm_config_.gain_controller1;
2330
2331 // Ensure default options.
2332 VerifyGainControlEnabledCorrectly();
2333 VerifyGainControlDefaultSettings();
2334
2335 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002336 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002337 EXPECT_FALSE(agc_config.enabled);
2338 send_parameters_.options.auto_gain_control = absl::nullopt;
2339
2340 send_parameters_.options.tx_agc_target_dbov = 5;
2341 SetSendParameters(send_parameters_);
2342 EXPECT_EQ(5, agc_config.target_level_dbfs);
2343 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2344
2345 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2346 SetSendParameters(send_parameters_);
2347 EXPECT_EQ(10, agc_config.compression_gain_db);
2348 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2349
2350 send_parameters_.options.tx_agc_limiter = false;
2351 SetSendParameters(send_parameters_);
2352 EXPECT_FALSE(agc_config.enable_limiter);
2353 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2354
2355 SetSendParameters(send_parameters_);
2356 // Expect all options to have been preserved.
2357 EXPECT_FALSE(agc_config.enabled);
2358 EXPECT_EQ(5, agc_config.target_level_dbfs);
2359 EXPECT_EQ(10, agc_config.compression_gain_db);
2360 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002361}
2362
minyue6b825df2016-10-31 04:08:32 -07002363TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2364 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002365 send_parameters_.options.audio_network_adaptor = true;
2366 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002367 SetSendParameters(send_parameters_);
2368 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002369 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002370}
2371
2372TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2373 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002374 send_parameters_.options.audio_network_adaptor = true;
2375 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002376 SetSendParameters(send_parameters_);
2377 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002378 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002379 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002380 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002381 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002382 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002383}
2384
2385TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2386 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002387 send_parameters_.options.audio_network_adaptor = true;
2388 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002389 SetSendParameters(send_parameters_);
2390 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002391 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002392 const int initial_num = call_.GetNumCreatedSendStreams();
2393 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002394 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002395 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2396 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002397 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002398 // AudioSendStream not expected to be recreated.
2399 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2400 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002401 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002402}
2403
michaelt6672b262017-01-11 10:17:59 -08002404class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2405 : public WebRtcVoiceEngineTestFake {
2406 public:
2407 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2408 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002409 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2410 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002411 "Enabled/") {}
2412};
2413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002414// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002415// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002416TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002417 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002418 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419}
2420
2421TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2422 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002424 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002425 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002426 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002427 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002428 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002429 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002430
solenberg85a04962015-10-27 03:35:21 -07002431 // Check stats for the added streams.
2432 {
2433 cricket::VoiceMediaInfo info;
2434 EXPECT_EQ(true, channel_->GetStats(&info));
2435
2436 // We have added one send stream. We should see the stats we've set.
2437 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002438 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002439 // We have added one receive stream. We should see empty stats.
2440 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002441 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002442 }
solenberg1ac56142015-10-13 03:58:19 -07002443
solenberg566ef242015-11-06 15:34:49 -08002444 // Start sending - this affects some reported stats.
2445 {
2446 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002447 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002448 EXPECT_EQ(true, channel_->GetStats(&info));
2449 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002450 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002451 }
2452
solenberg2100c0b2017-03-01 11:29:29 -08002453 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002454 {
2455 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002456 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002457 EXPECT_EQ(true, channel_->GetStats(&info));
2458 EXPECT_EQ(1u, info.senders.size());
2459 EXPECT_EQ(0u, info.receivers.size());
2460 }
solenberg1ac56142015-10-13 03:58:19 -07002461
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002462 // Deliver a new packet - a default receive stream should be created and we
2463 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002464 {
2465 cricket::VoiceMediaInfo info;
2466 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2467 SetAudioReceiveStreamStats();
2468 EXPECT_EQ(true, channel_->GetStats(&info));
2469 EXPECT_EQ(1u, info.senders.size());
2470 EXPECT_EQ(1u, info.receivers.size());
2471 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002472 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002473 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474}
2475
2476// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002477// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002478TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002479 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002480 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2481 EXPECT_TRUE(AddRecvStream(kSsrcY));
2482 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483}
2484
2485// Test that the local SSRC is the same on sending and receiving channels if the
2486// receive channel is created before the send channel.
2487TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002489 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002490 EXPECT_TRUE(
2491 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002492 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2493 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494}
2495
2496// Test that we can properly receive packets.
2497TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002498 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002499 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002501
Yves Gerey665174f2018-06-19 15:03:05 +02002502 EXPECT_TRUE(
2503 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504}
2505
2506// Test that we can properly receive packets on multiple streams.
2507TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002508 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002509 const uint32_t ssrc1 = 1;
2510 const uint32_t ssrc2 = 2;
2511 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002512 EXPECT_TRUE(AddRecvStream(ssrc1));
2513 EXPECT_TRUE(AddRecvStream(ssrc2));
2514 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002515 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002516 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002517 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002518 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002519 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520 }
mflodman3d7db262016-04-29 00:57:13 -07002521
2522 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2523 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2524 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2525
2526 EXPECT_EQ(s1.received_packets(), 0);
2527 EXPECT_EQ(s2.received_packets(), 0);
2528 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002529
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002530 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002531 EXPECT_EQ(s1.received_packets(), 0);
2532 EXPECT_EQ(s2.received_packets(), 0);
2533 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002534
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002536 EXPECT_EQ(s1.received_packets(), 1);
2537 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2538 EXPECT_EQ(s2.received_packets(), 0);
2539 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002540
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002541 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002542 EXPECT_EQ(s1.received_packets(), 1);
2543 EXPECT_EQ(s2.received_packets(), 1);
2544 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2545 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002546
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002547 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002548 EXPECT_EQ(s1.received_packets(), 1);
2549 EXPECT_EQ(s2.received_packets(), 1);
2550 EXPECT_EQ(s3.received_packets(), 1);
2551 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002552
mflodman3d7db262016-04-29 00:57:13 -07002553 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2554 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2555 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556}
2557
solenberg2100c0b2017-03-01 11:29:29 -08002558// Test that receiving on an unsignaled stream works (a stream is created).
2559TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002560 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002561 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002562
solenberg7e63ef02015-11-20 00:19:43 -08002563 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002564
Mirko Bonadeif859e552018-05-30 15:31:29 +02002565 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002566 EXPECT_TRUE(
2567 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002568}
2569
Seth Hampson5897a6e2018-04-03 11:16:33 -07002570// Tests that when we add a stream without SSRCs, but contains a stream_id
2571// that it is stored and its stream id is later used when the first packet
2572// arrives to properly create a receive stream with a sync label.
2573TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2574 const char kSyncLabel[] = "sync_label";
2575 EXPECT_TRUE(SetupChannel());
2576 cricket::StreamParams unsignaled_stream;
2577 unsignaled_stream.set_stream_ids({kSyncLabel});
2578 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2579 // The stream shouldn't have been created at this point because it doesn't
2580 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002581 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002582
2583 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2584
Mirko Bonadeif859e552018-05-30 15:31:29 +02002585 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002586 EXPECT_TRUE(
2587 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2588 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2589
2590 // Removing the unsignaled stream clears the cached parameters. If a new
2591 // default unsignaled receive stream is created it will not have a sync group.
2592 channel_->RemoveRecvStream(0);
2593 channel_->RemoveRecvStream(kSsrc1);
2594
2595 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2596
Mirko Bonadeif859e552018-05-30 15:31:29 +02002597 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002598 EXPECT_TRUE(
2599 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2600 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2601}
2602
solenberg2100c0b2017-03-01 11:29:29 -08002603// Test that receiving N unsignaled stream works (streams will be created), and
2604// that packets are forwarded to them all.
2605TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002606 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002607 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002608 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2609
solenberg2100c0b2017-03-01 11:29:29 -08002610 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002611 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002612 rtc::SetBE32(&packet[8], ssrc);
2613 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002614
solenberg2100c0b2017-03-01 11:29:29 -08002615 // Verify we have one new stream for each loop iteration.
2616 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002617 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2618 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002619 }
mflodman3d7db262016-04-29 00:57:13 -07002620
solenberg2100c0b2017-03-01 11:29:29 -08002621 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002622 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002623 rtc::SetBE32(&packet[8], ssrc);
2624 DeliverPacket(packet, sizeof(packet));
2625
solenbergebb349d2017-03-13 05:46:15 -07002626 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002627 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2628 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2629 }
2630
2631 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2632 constexpr uint32_t kAnotherSsrc = 667;
2633 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002634 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002635
2636 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002637 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002638 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002639 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002640 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2641 EXPECT_EQ(2, streams[i]->received_packets());
2642 }
2643 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2644 EXPECT_EQ(1, streams[i]->received_packets());
2645 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002646 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002647}
2648
solenberg2100c0b2017-03-01 11:29:29 -08002649// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002650// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002651TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002653 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002654 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2655
2656 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002657 const uint32_t signaled_ssrc = 1;
2658 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002659 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002660 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002661 EXPECT_TRUE(
2662 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002663 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002664
2665 // Note that the first unknown SSRC cannot be 0, because we only support
2666 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002667 const uint32_t unsignaled_ssrc = 7011;
2668 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002669 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002670 EXPECT_TRUE(
2671 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002672 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002673
2674 DeliverPacket(packet, sizeof(packet));
2675 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2676
2677 rtc::SetBE32(&packet[8], signaled_ssrc);
2678 DeliverPacket(packet, sizeof(packet));
2679 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002680 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002681}
2682
solenberg4904fb62017-02-17 12:01:14 -08002683// Two tests to verify that adding a receive stream with the same SSRC as a
2684// previously added unsignaled stream will only recreate underlying stream
2685// objects if the stream parameters have changed.
2686TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2687 EXPECT_TRUE(SetupChannel());
2688
2689 // Spawn unsignaled stream with SSRC=1.
2690 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002691 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002692 EXPECT_TRUE(
2693 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002694
2695 // Verify that the underlying stream object in Call is not recreated when a
2696 // stream with SSRC=1 is added.
2697 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002698 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002699 int audio_receive_stream_id = streams.front()->id();
2700 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002701 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002702 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2703}
2704
2705TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2706 EXPECT_TRUE(SetupChannel());
2707
2708 // Spawn unsignaled stream with SSRC=1.
2709 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002710 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002711 EXPECT_TRUE(
2712 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002713
2714 // Verify that the underlying stream object in Call *is* recreated when a
2715 // stream with SSRC=1 is added, and which has changed stream parameters.
2716 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002717 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002718 int audio_receive_stream_id = streams.front()->id();
2719 cricket::StreamParams stream_params;
2720 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002721 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002722 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002723 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002724 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2725}
2726
solenberg1ac56142015-10-13 03:58:19 -07002727// Test that AddRecvStream creates new stream.
2728TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002729 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002730 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731}
2732
2733// Test that after adding a recv stream, we do not decode more codecs than
2734// those previously passed into SetRecvCodecs.
2735TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002736 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002737 cricket::AudioRecvParameters parameters;
2738 parameters.codecs.push_back(kIsacCodec);
2739 parameters.codecs.push_back(kPcmuCodec);
2740 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002741 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002742 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2743 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2744 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002745}
2746
2747// Test that we properly clean up any streams that were added, even if
2748// not explicitly removed.
2749TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002750 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002752 EXPECT_TRUE(AddRecvStream(1));
2753 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002754
Mirko Bonadeif859e552018-05-30 15:31:29 +02002755 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2756 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757 delete channel_;
2758 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002759 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2760 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761}
2762
wu@webrtc.org78187522013-10-07 23:32:02 +00002763TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002764 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002765 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002766}
2767
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002768TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002769 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002770 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002771 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002772}
2773
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002774// Test the InsertDtmf on default send stream as caller.
2775TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002776 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002777}
2778
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002779// Test the InsertDtmf on default send stream as callee
2780TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002781 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002782}
2783
2784// Test the InsertDtmf on specified send stream as caller.
2785TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002786 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002787}
2788
2789// Test the InsertDtmf on specified send stream as callee.
2790TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002791 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002792}
2793
Johannes Kron9190b822018-10-29 11:22:05 +01002794// Test propagation of extmap allow mixed setting.
2795TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2796 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2797}
2798TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2799 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2800}
2801TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2802 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2803}
2804TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2805 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2806}
2807
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002808TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002809 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002810 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002811 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2812 .Times(9)
2813 .WillRepeatedly(Return(false));
2814 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2815 .Times(4)
2816 .WillRepeatedly(Return(false));
2817 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2818 .Times(2)
2819 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002820
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002821 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002822 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823
solenberg246b8172015-12-08 09:50:23 -08002824 // Nothing set in AudioOptions, so everything should be as default.
2825 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002826 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002827 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002828 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002829 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002830 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002831 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832
Sam Zackrissonba502232019-01-04 10:36:48 +01002833 // Turn typing detection off.
2834 send_parameters_.options.typing_detection = false;
2835 SetSendParameters(send_parameters_);
2836 EXPECT_FALSE(IsTypingDetectionEnabled());
2837
2838 // Leave typing detection unchanged, but non-default.
2839 send_parameters_.options.typing_detection = absl::nullopt;
2840 SetSendParameters(send_parameters_);
2841 EXPECT_FALSE(IsTypingDetectionEnabled());
2842
2843 // Turn typing detection on.
2844 send_parameters_.options.typing_detection = true;
2845 SetSendParameters(send_parameters_);
2846 EXPECT_TRUE(IsTypingDetectionEnabled());
2847
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002849 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002850 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002851 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852
2853 // Turn echo cancellation back on, with settings, and make sure
2854 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002855 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002856 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002857 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002859 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2860 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002861 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002862 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002863 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002864
2865 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002866 send_parameters_.options.delay_agnostic_aec = false;
2867 send_parameters_.options.extended_filter_aec = false;
2868 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002869 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002870 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002871
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002872 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002873 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002874 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002875 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002876
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002878 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002879 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002880 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002881 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
2883 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002885 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002886 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002887 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002888
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002889 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002890 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002891 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002892 send_parameters_.options.noise_suppression = false;
2893 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002894 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002895 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002896 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002897 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002898 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899
solenberg1ac56142015-10-13 03:58:19 -07002900 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002901 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002902 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002903 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002904 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002905 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906}
2907
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002909 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002910 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2911 .Times(8)
2912 .WillRepeatedly(Return(false));
2913 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2914 .Times(8)
2915 .WillRepeatedly(Return(false));
2916 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2917 .Times(8)
2918 .WillRepeatedly(Return(false));
2919 EXPECT_CALL(adm_, RecordingIsInitialized())
2920 .Times(2)
2921 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002922 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2923 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002924 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002925
kwiberg686a8ef2016-02-26 03:00:35 -08002926 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002927 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2928 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2929 cricket::AudioOptions(),
2930 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002931 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002932 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2933 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2934 cricket::AudioOptions(),
2935 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936
2937 // Have to add a stream to make SetSend work.
2938 cricket::StreamParams stream1;
2939 stream1.ssrcs.push_back(1);
2940 channel1->AddSendStream(stream1);
2941 cricket::StreamParams stream2;
2942 stream2.ssrcs.push_back(2);
2943 channel2->AddSendStream(stream2);
2944
2945 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002946 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002947 parameters_options_all.options.echo_cancellation = true;
2948 parameters_options_all.options.auto_gain_control = true;
2949 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002952 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002953 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002954 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002955 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002956 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002957 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002958 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002960
2961 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002962 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002963 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002964 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002965 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002966 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002967 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002968 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002969 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002970 expected_options.echo_cancellation = true;
2971 expected_options.auto_gain_control = true;
2972 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002973 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002974
2975 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002976 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002977 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002980 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002981 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002982 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002983 expected_options.echo_cancellation = true;
2984 expected_options.auto_gain_control = false;
2985 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002986 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002988 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002989 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002990 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002991 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002992 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002994 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002995 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002996 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002997 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002998 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003002 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003003 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003004 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003007 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3008 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003009 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3010 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003011 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003012 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003013 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003014 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003015 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003016 expected_options.echo_cancellation = true;
3017 expected_options.auto_gain_control = false;
3018 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003019 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020}
3021
wu@webrtc.orgde305012013-10-31 15:40:38 +00003022// This test verifies DSCP settings are properly applied on voice media channel.
3023TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003024 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003025 cricket::FakeNetworkInterface network_interface;
3026 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003027 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003028 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003029
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003030 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003031
Sebastian Jansson84848f22018-11-16 10:40:36 +01003032 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3033 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3034 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003035 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003036 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3037 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3038
3039 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003040 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3041 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3042 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003043 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003044 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3045
3046 // Create a send stream to configure
3047 EXPECT_TRUE(
3048 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3049 parameters = channel->GetRtpSendParameters(kSsrcZ);
3050 ASSERT_FALSE(parameters.encodings.empty());
3051
3052 // Various priorities map to various dscp values.
3053 parameters.encodings[0].network_priority = 4.0;
3054 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003055 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003056 parameters.encodings[0].network_priority = 0.5;
3057 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3058 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3059
3060 // A bad priority does not change the dscp value.
3061 parameters.encodings[0].network_priority = 0.0;
3062 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3063 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003064
Tim Haloun6ca98362018-09-17 17:06:08 -07003065 // Packets should also self-identify their dscp in PacketOptions.
3066 const uint8_t kData[10] = {0};
3067 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003068 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003069
nisse51542be2016-02-12 02:27:06 -08003070 // Verify that setting the option to false resets the
3071 // DiffServCodePoint.
3072 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003073 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3074 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3075 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003076 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003077 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3078 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3079
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003080 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003081}
3082
solenberg4bac9c52015-10-09 02:32:53 -07003083TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003084 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003085 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003086 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003087 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003088 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003089 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3090 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3091 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003092}
3093
solenberg2100c0b2017-03-01 11:29:29 -08003094TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003095 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003096
3097 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003098 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003099 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3100
3101 // Should remember the volume "2" which will be set on new unsignaled streams,
3102 // and also set the gain to 2 on existing unsignaled streams.
3103 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3104 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3105
3106 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3107 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3108 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3109 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3110 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3111 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3112
3113 // Setting gain with SSRC=0 should affect all unsignaled streams.
3114 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003115 if (kMaxUnsignaledRecvStreams > 1) {
3116 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3117 }
solenberg2100c0b2017-03-01 11:29:29 -08003118 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3119
3120 // Setting gain on an individual stream affects only that.
3121 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003122 if (kMaxUnsignaledRecvStreams > 1) {
3123 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3124 }
solenberg2100c0b2017-03-01 11:29:29 -08003125 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003126}
3127
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003128TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3129 EXPECT_TRUE(SetupChannel());
3130 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3131 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3132
3133 cricket::StreamParams stream;
3134 stream.ssrcs.push_back(kSsrcY);
3135 EXPECT_TRUE(channel_->AddRecvStream(stream));
3136 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3137 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3138 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3139}
3140
3141TEST_F(WebRtcVoiceEngineTestFake,
3142 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3143 // Here base minimum delay is abbreviated to delay in comments for shortness.
3144 EXPECT_TRUE(SetupChannel());
3145
3146 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3147 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3148 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3149 // Check that it doesn't provide default values for unknown ssrc.
3150 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3151
3152 // Check that default value for unsignaled streams is 0.
3153 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3154
3155 // Should remember the delay 100 which will be set on new unsignaled streams,
3156 // and also set the delay to 100 on existing unsignaled streams.
3157 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3158 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3159 // Check that it doesn't provide default values for unknown ssrc.
3160 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3161
3162 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3163 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3164 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3165 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3166 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3167 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3168
3169 // Setting delay with SSRC=0 should affect all unsignaled streams.
3170 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3171 if (kMaxUnsignaledRecvStreams > 1) {
3172 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3173 }
3174 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3175
3176 // Setting delay on an individual stream affects only that.
3177 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3178 if (kMaxUnsignaledRecvStreams > 1) {
3179 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3180 }
3181 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3182 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3183 // Check that it doesn't provide default values for unknown ssrc.
3184 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3185}
3186
Seth Hampson845e8782018-03-02 11:34:10 -08003187TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003188 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003189 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003190
solenbergff976312016-03-30 23:28:51 -07003191 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003192 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003193 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003194 // Creating two channels to make sure that sync label is set properly for both
3195 // the default voice channel and following ones.
3196 EXPECT_TRUE(channel_->AddRecvStream(sp));
3197 sp.ssrcs[0] += 1;
3198 EXPECT_TRUE(channel_->AddRecvStream(sp));
3199
Mirko Bonadeif859e552018-05-30 15:31:29 +02003200 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003201 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003202 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003203 << "SyncGroup should be set based on stream id";
3204 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003205 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003206 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003207}
3208
solenberg3a941542015-11-16 07:34:50 -08003209// TODO(solenberg): Remove, once recv streams are configured through Call.
3210// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003211TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003212 // Test that setting the header extensions results in the expected state
3213 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003214 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003215 ssrcs.push_back(223);
3216 ssrcs.push_back(224);
3217
solenbergff976312016-03-30 23:28:51 -07003218 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003219 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003220 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003221 EXPECT_TRUE(
3222 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003223 }
3224
Mirko Bonadeif859e552018-05-30 15:31:29 +02003225 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003226 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003227 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003228 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003229 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003230 }
3231
3232 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003233 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003234 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003235 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003236 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003237 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003238 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003239 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003240 EXPECT_NE(nullptr, s);
3241 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003242 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3243 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244 for (const auto& s_ext : s_exts) {
3245 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003246 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003247 }
3248 }
3249 }
3250 }
3251
3252 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003253 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003254 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003255 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003256 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003257 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003259}
3260
3261TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3262 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003263 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003264 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003265 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003266 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3267 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003269 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003270
solenbergff976312016-03-30 23:28:51 -07003271 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 cricket::WebRtcVoiceMediaChannel* media_channel =
3273 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003274 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 EXPECT_TRUE(media_channel->AddRecvStream(
3276 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3277
Mirko Bonadeif859e552018-05-30 15:31:29 +02003278 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003279 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003280 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003281 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003282 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003283 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003284 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003285 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003286}
Minyue2013aec2015-05-13 14:14:42 +02003287
solenberg0a617e22015-10-20 15:49:38 -07003288// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003289// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003290TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003291 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_TRUE(AddRecvStream(kSsrcY));
3293 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003294 EXPECT_TRUE(
3295 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003296 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3297 EXPECT_TRUE(AddRecvStream(kSsrcW));
3298 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003299}
3300
solenberg7602aab2016-11-14 11:30:07 -08003301TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3302 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003303 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003304 EXPECT_TRUE(
3305 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003306 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3307 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3308 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003309 EXPECT_TRUE(
3310 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3312 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003313}
stefan658910c2015-09-03 05:48:32 -07003314
deadbeef884f5852016-01-15 09:20:04 -08003315TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003316 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003317 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3318 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003319
3320 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003321 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3322 EXPECT_TRUE(AddRecvStream(kSsrcX));
3323 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003324
3325 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003326 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3327 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003328
3329 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003330 channel_->SetRawAudioSink(kSsrcX, nullptr);
3331 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003332}
3333
solenberg2100c0b2017-03-01 11:29:29 -08003334TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003335 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003336 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3337 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003338 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3339 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003340
3341 // Should be able to set a default sink even when no stream exists.
3342 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3343
solenberg2100c0b2017-03-01 11:29:29 -08003344 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3345 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003346 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003347 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003348
3349 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003350 channel_->SetRawAudioSink(kSsrc0, nullptr);
3351 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003352
3353 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003354 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3355 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003356
3357 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003358 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003359 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003360 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3361
3362 // Spawn another unsignaled stream - it should be assigned the default sink
3363 // and the previous unsignaled stream should lose it.
3364 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3365 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3366 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3367 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003368 if (kMaxUnsignaledRecvStreams > 1) {
3369 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3370 }
solenberg2100c0b2017-03-01 11:29:29 -08003371 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3372
3373 // Reset the default sink - the second unsignaled stream should lose it.
3374 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003375 if (kMaxUnsignaledRecvStreams > 1) {
3376 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3377 }
solenberg2100c0b2017-03-01 11:29:29 -08003378 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3379
3380 // Try setting the default sink while two streams exists.
3381 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003382 if (kMaxUnsignaledRecvStreams > 1) {
3383 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3384 }
solenberg2100c0b2017-03-01 11:29:29 -08003385 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3386
3387 // Try setting the sink for the first unsignaled stream using its known SSRC.
3388 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003389 if (kMaxUnsignaledRecvStreams > 1) {
3390 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3391 }
solenberg2100c0b2017-03-01 11:29:29 -08003392 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003393 if (kMaxUnsignaledRecvStreams > 1) {
3394 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3395 }
deadbeef884f5852016-01-15 09:20:04 -08003396}
3397
skvlad7a43d252016-03-22 15:32:27 -07003398// Test that, just like the video channel, the voice channel communicates the
3399// network state to the call.
3400TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003401 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003402
3403 EXPECT_EQ(webrtc::kNetworkUp,
3404 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3405 EXPECT_EQ(webrtc::kNetworkUp,
3406 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3407
3408 channel_->OnReadyToSend(false);
3409 EXPECT_EQ(webrtc::kNetworkDown,
3410 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3411 EXPECT_EQ(webrtc::kNetworkUp,
3412 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3413
3414 channel_->OnReadyToSend(true);
3415 EXPECT_EQ(webrtc::kNetworkUp,
3416 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3417 EXPECT_EQ(webrtc::kNetworkUp,
3418 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3419}
3420
aleloi18e0b672016-10-04 02:45:47 -07003421// Test that playout is still started after changing parameters
3422TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3423 SetupRecvStream();
3424 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003425 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003426
3427 // Changing RTP header extensions will recreate the AudioReceiveStream.
3428 cricket::AudioRecvParameters parameters;
3429 parameters.extensions.push_back(
3430 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3431 channel_->SetRecvParameters(parameters);
3432
solenberg2100c0b2017-03-01 11:29:29 -08003433 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003434}
3435
Zhi Huangfa266ef2017-12-13 10:27:46 -08003436// Tests when GetSources is called with non-existing ssrc, it will return an
3437// empty list of RtpSource without crashing.
3438TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3439 // Setup an recv stream with |kSsrcX|.
3440 SetupRecvStream();
3441 cricket::WebRtcVoiceMediaChannel* media_channel =
3442 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3443 // Call GetSources with |kSsrcY| which doesn't exist.
3444 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3445 EXPECT_EQ(0u, sources.size());
3446}
3447
stefan658910c2015-09-03 05:48:32 -07003448// Tests that the library initializes and shuts down properly.
3449TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003450 // If the VoiceEngine wants to gather available codecs early, that's fine but
3451 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003452 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3453 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003454 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003455 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003456 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003457 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003458 task_queue_factory.get(), &adm,
3459 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003460 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003461 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003462 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003463 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003464 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003465 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3466 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3467 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003468 EXPECT_TRUE(channel != nullptr);
3469 delete channel;
solenbergff976312016-03-30 23:28:51 -07003470}
stefan658910c2015-09-03 05:48:32 -07003471
solenbergff976312016-03-30 23:28:51 -07003472// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003473TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003474 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3475 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003476 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003477 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003478 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003479 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003480 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003481 {
peaha9cc40b2017-06-29 08:32:09 -07003482 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003483 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003484 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003485 task_queue_factory.get(), &adm,
3486 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003487 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003488 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003489 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003490 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003491 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003492 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3493 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3494 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003495 EXPECT_TRUE(channel != nullptr);
3496 delete channel;
3497 }
stefan658910c2015-09-03 05:48:32 -07003498}
3499
ossu20a4b3f2017-04-27 02:08:52 -07003500// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3501TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003502 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3503 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003504 // TODO(ossu): Why are the payload types of codecs with non-static payload
3505 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003506 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003507 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003508 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003509 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003510 task_queue_factory.get(), &adm,
3511 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003512 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003513 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003514 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003515 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003516 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003517 (clockrate == 0 || codec.clockrate == clockrate);
3518 };
3519 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003520 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003521 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003522 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003523 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003524 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003525 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003526 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003527 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003528 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003529 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003530 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003531 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3532 // Remove these checks once both send and receive side assigns payload
3533 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003534 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003535 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003536 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003537 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003538 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003539 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003540 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003541 EXPECT_EQ(111, codec.id);
3542 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3543 EXPECT_EQ("10", codec.params.find("minptime")->second);
3544 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3545 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003546 }
3547 }
stefan658910c2015-09-03 05:48:32 -07003548}
3549
3550// Tests that VoE supports at least 32 channels
3551TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003552 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3553 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003554 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003555 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003556 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003557 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003558 task_queue_factory.get(), &adm,
3559 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003560 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003561 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003562 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003563 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003564 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003565
3566 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003567 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003568 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003569 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3570 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3571 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003572 if (!channel)
3573 break;
stefan658910c2015-09-03 05:48:32 -07003574 channels[num_channels++] = channel;
3575 }
3576
Mirko Bonadeif859e552018-05-30 15:31:29 +02003577 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003578 EXPECT_EQ(expected, num_channels);
3579
3580 while (num_channels > 0) {
3581 delete channels[--num_channels];
3582 }
stefan658910c2015-09-03 05:48:32 -07003583}
3584
3585// Test that we set our preferred codecs properly.
3586TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003587 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3588 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003589 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3590 // - Check that our builtin codecs are usable by Channel.
3591 // - The codecs provided by the engine is usable by Channel.
3592 // It does not check that the codecs in the RecvParameters are actually
3593 // what we sent in - though it's probably reasonable to expect so, if
3594 // SetRecvParameters returns true.
3595 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003596 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003597 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003598 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003599 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003600 task_queue_factory.get(), &adm,
3601 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003602 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003603 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003604 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003605 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003606 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003607 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003608 cricket::AudioOptions(),
3609 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003610 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003611 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003612 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003613}
ossu9def8002017-02-09 05:14:32 -08003614
3615TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3616 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003617 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3618 {48000, 2, 16000, 10000, 20000}};
3619 spec1.info.allow_comfort_noise = false;
3620 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003621 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003622 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3623 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003624 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003625 specs.push_back(webrtc::AudioCodecSpec{
3626 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3627 {16000, 1, 13300}});
3628 specs.push_back(
3629 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3630 specs.push_back(
3631 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003632
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003633 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3634 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003635 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3636 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3637 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003638 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003639 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003640 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003641 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003642
peaha9cc40b2017-06-29 08:32:09 -07003643 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003644 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003645 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3646 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003647 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003648 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003649 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003650 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003651
3652 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3653 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003654 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3655 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3656 if (codecs.size() > index)
3657 return codecs[index];
3658 return missing_codec;
3659 };
ossu9def8002017-02-09 05:14:32 -08003660
3661 // Ensure the general codecs are generated first and in order.
3662 for (size_t i = 0; i != specs.size(); ++i) {
3663 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3664 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3665 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3666 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3667 }
3668
3669 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003670 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003671 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3672 for (size_t i = 0; i != codecs.size(); ++i) {
3673 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003674 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003675 codec.clockrate == format.clockrate_hz &&
3676 codec.channels == format.num_channels) {
3677 return rtc::checked_cast<int>(i);
3678 }
3679 }
3680 return -1;
3681 };
ossu9def8002017-02-09 05:14:32 -08003682
3683 // Ensure all supplementary codecs are generated last. Their internal ordering
3684 // is not important.
3685 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3686 const int num_specs = static_cast<int>(specs.size());
3687 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3688 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3689 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3690 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3691 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3692 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3693 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3694}