blob: a76186d8979219fd400e52ef19a8ccb100bc14ef [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010019#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "call/call.h"
21#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "media/base/fake_media_engine.h"
23#include "media/base/fake_network_interface.h"
24#include "media/base/fake_rtp.h"
25#include "media/base/media_constants.h"
26#include "media/engine/fake_webrtc_call.h"
27#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/audio_device/include/mock_audio_device.h"
29#include "modules/audio_processing/include/mock_audio_processing.h"
30#include "pc/channel.h"
31#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010033#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "test/field_trial.h"
35#include "test/gtest.h"
36#include "test/mock_audio_decoder_factory.h"
37#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
Elad Alon157540a2019-02-08 23:37:52 +010039using ::testing::_;
40using ::testing::ContainerEq;
41using ::testing::Contains;
42using ::testing::Field;
43using ::testing::Return;
44using ::testing::ReturnPointee;
45using ::testing::SaveArg;
46using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000047
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010049using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050
solenberg418b7d32017-06-13 00:38:27 -070051constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070052
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
54const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070055const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
57const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
59const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020060const cricket::AudioCodec kTelephoneEventCodec1(106,
61 "telephone-event",
62 8000,
63 0,
64 1);
65const cricket::AudioCodec kTelephoneEventCodec2(107,
66 "telephone-event",
67 32000,
68 0,
69 1);
solenberg2779bab2016-11-17 04:45:19 -080070
solenberg2100c0b2017-03-01 11:29:29 -080071const uint32_t kSsrc0 = 0;
72const uint32_t kSsrc1 = 1;
73const uint32_t kSsrcX = 0x99;
74const uint32_t kSsrcY = 0x17;
75const uint32_t kSsrcZ = 0x42;
76const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020077const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
solenberg971cab02016-06-14 10:02:41 -070079constexpr int kRtpHistoryMs = 5000;
80
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010081constexpr webrtc::AudioProcessing::Config::GainController1::Mode
82 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010083#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010084 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010085#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010086 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010087#endif
88
89constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
90 webrtc::NoiseSuppression::kHigh;
91
solenberg9a5f032222017-03-15 06:14:12 -070092void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
93 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010094
95 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010096 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010097 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010098 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070099#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200100 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200101 *adm,
102 SetPlayoutDevice(
103 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
104 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200105 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700106#else
107 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
108#endif // #if defined(WEBRTC_WIN)
109 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200110 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700111 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100112#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200113 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200114 *adm,
115 SetRecordingDevice(
116 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
117 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200118 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100119#else
120 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
121#endif // #if defined(WEBRTC_WIN)
122 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200123 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
124 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100125 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700126 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
127 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
128 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100129
130 // Teardown.
131 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
132 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
133 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
134 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200135 EXPECT_CALL(*adm, Release())
136 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100137 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700138}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200139} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140
solenbergff976312016-03-30 23:28:51 -0700141// Tests that our stub library "works".
142TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100143 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
144 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700145 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700146 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700147 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
148 new rtc::RefCountedObject<
149 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700150 webrtc::AudioProcessing::Config apm_config;
151 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
152 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200153 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700154 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700155 {
ossuc54071d2016-08-17 02:45:41 -0700156 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100157 task_queue_factory.get(), &adm,
158 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100159 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700160 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700161 }
solenbergff976312016-03-30 23:28:51 -0700162}
163
deadbeef884f5852016-01-15 09:20:04 -0800164class FakeAudioSink : public webrtc::AudioSinkInterface {
165 public:
166 void OnData(const Data& audio) override {}
167};
168
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800169class FakeAudioSource : public cricket::AudioSource {
170 void SetSink(Sink* sink) override {}
171};
172
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200173class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 public:
stefanba4c0e42016-02-04 04:12:24 -0800175 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
176
177 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100178 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
179 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700180 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700181 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100182 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700183 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800184 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700185 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800186 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700187 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
188 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200189 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700190 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800191 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100192 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700194 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800195 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700196 // factories. Those tests should probably be moved elsewhere.
197 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
198 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100199 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100200 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
201 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200207 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100209 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100210 VerifyGainControlEnabledCorrectly();
211 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
solenberg8189b022016-06-14 12:13:00 -0700213
solenbergff976312016-03-30 23:28:51 -0700214 bool SetupChannel() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200215 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100216 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
217 cricket::AudioOptions(),
218 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200219 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000220 }
solenberg8189b022016-06-14 12:13:00 -0700221
solenbergff976312016-03-30 23:28:51 -0700222 bool SetupRecvStream() {
223 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700224 return false;
225 }
solenberg2100c0b2017-03-01 11:29:29 -0800226 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700227 }
solenberg8189b022016-06-14 12:13:00 -0700228
solenbergff976312016-03-30 23:28:51 -0700229 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200230 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
231 }
232
233 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700234 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000235 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
Florent Castellidacec712018-05-24 16:24:21 +0200237 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800238 return false;
239 }
peaha9cc40b2017-06-29 08:32:09 -0700240 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800241 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 }
solenberg8189b022016-06-14 12:13:00 -0700243
244 bool AddRecvStream(uint32_t ssrc) {
245 EXPECT_TRUE(channel_);
246 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
247 }
248
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700250 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700251 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800252 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
253 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700254 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800255 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256 }
solenberg8189b022016-06-14 12:13:00 -0700257
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700259 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700260 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 }
solenberg8189b022016-06-14 12:13:00 -0700262
Yves Gerey665174f2018-06-19 15:03:05 +0200263 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100265 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
266 const auto* send_stream = call_.GetAudioSendStream(ssrc);
267 EXPECT_TRUE(send_stream);
268 return *send_stream;
269 }
270
deadbeef884f5852016-01-15 09:20:04 -0800271 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
272 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
273 EXPECT_TRUE(recv_stream);
274 return *recv_stream;
275 }
276
solenberg3a941542015-11-16 07:34:50 -0800277 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800278 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800279 }
280
solenberg7add0582015-11-20 09:59:34 -0800281 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800282 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800283 }
284
solenberg059fb442016-10-26 05:12:24 -0700285 void SetSend(bool enable) {
286 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700287 if (enable) {
288 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
289 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
290 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200291 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700292 }
solenberg059fb442016-10-26 05:12:24 -0700293 channel_->SetSend(enable);
294 }
295
296 void SetSendParameters(const cricket::AudioSendParameters& params) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200297 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenberg059fb442016-10-26 05:12:24 -0700298 ASSERT_TRUE(channel_);
299 EXPECT_TRUE(channel_->SetSendParameters(params));
300 }
301
Yves Gerey665174f2018-06-19 15:03:05 +0200302 void SetAudioSend(uint32_t ssrc,
303 bool enable,
304 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700305 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700306 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700307 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700308 if (enable && options) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200309 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
minyue6b825df2016-10-31 04:08:32 -0700310 }
311 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700312 }
313
Yves Gerey665174f2018-06-19 15:03:05 +0200314 void TestInsertDtmf(uint32_t ssrc,
315 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800316 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700317 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700319 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200321 EXPECT_TRUE(
322 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000323 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700326 SetSendParameters(send_parameters_);
327 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800329 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800330 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700331 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000333
334 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700335 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800336 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200337 EXPECT_TRUE(
338 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000339 }
340
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800342 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 // Test send.
345 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800346 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100347 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800348 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800349 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800350 EXPECT_EQ(codec.id, telephone_event.payload_type);
351 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100352 EXPECT_EQ(2, telephone_event.event_code);
353 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 }
355
Johannes Kron9190b822018-10-29 11:22:05 +0100356 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
357 // For a caller, the answer will be applied in set remote description
358 // where SetSendParameters() is called.
359 EXPECT_TRUE(SetupChannel());
360 EXPECT_TRUE(
361 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
362 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
363 SetSendParameters(send_parameters_);
364 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
365 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
366 }
367
368 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
369 // For a callee, the answer will be applied in set local description
370 // where SetExtmapAllowMixed() and AddSendStream() are called.
371 EXPECT_TRUE(SetupChannel());
372 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
373 EXPECT_TRUE(
374 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
375
376 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
377 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
378 }
379
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000380 // Test that send bandwidth is set correctly.
381 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000382 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
383 // |expected_result| is the expected result from SetMaxSendBandwidth().
384 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700385 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
386 int max_bitrate,
387 bool expected_result,
388 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200389 cricket::AudioSendParameters parameters;
390 parameters.codecs.push_back(codec);
391 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700392 if (expected_result) {
393 SetSendParameters(parameters);
394 } else {
395 EXPECT_FALSE(channel_->SetSendParameters(parameters));
396 }
solenberg2100c0b2017-03-01 11:29:29 -0800397 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 // Sets the per-stream maximum bitrate limit for the specified SSRC.
401 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700402 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700403 EXPECT_EQ(1UL, parameters.encodings.size());
404
Oskar Sundbom78807582017-11-16 11:09:55 +0100405 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800406 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700407 }
408
solenberg059fb442016-10-26 05:12:24 -0700409 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700410 cricket::AudioSendParameters send_parameters;
411 send_parameters.codecs.push_back(codec);
412 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700413 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700414 }
415
ossu20a4b3f2017-04-27 02:08:52 -0700416 void CheckSendCodecBitrate(int32_t ssrc,
417 const char expected_name[],
418 int expected_bitrate) {
419 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
420 EXPECT_EQ(expected_name, spec->format.name);
421 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700422 }
423
Danil Chapovalov00c71832018-06-15 15:58:38 +0200424 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700425 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700426 }
427
Danil Chapovalov00c71832018-06-15 15:58:38 +0200428 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
429 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700430 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
431 }
432
skvlade0d46372016-04-07 22:59:22 -0700433 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
434 int global_max,
435 int stream_max,
436 bool expected_result,
437 int expected_codec_bitrate) {
438 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800439 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700440
441 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700442 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800443 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700444
445 // Verify that reading back the parameters gives results
446 // consistent with the Set() result.
447 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800448 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700449 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
450 EXPECT_EQ(expected_result ? stream_max : -1,
451 resulting_parameters.encodings[0].max_bitrate_bps);
452
453 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800454 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700455 }
456
stefan13f1a0a2016-11-30 07:22:58 -0800457 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
458 int expected_min_bitrate_bps,
459 const char* start_bitrate_kbps,
460 int expected_start_bitrate_bps,
461 const char* max_bitrate_kbps,
462 int expected_max_bitrate_bps) {
463 EXPECT_TRUE(SetupSendStream());
464 auto& codecs = send_parameters_.codecs;
465 codecs.clear();
466 codecs.push_back(kOpusCodec);
467 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
468 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
469 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100470 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
471 SetSdpBitrateParameters(
472 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
473 expected_min_bitrate_bps),
474 Field(&BitrateConstraints::start_bitrate_bps,
475 expected_start_bitrate_bps),
476 Field(&BitrateConstraints::max_bitrate_bps,
477 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800478
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100479 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800480 }
481
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000482 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700483 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000484
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000487
488 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700489 send_parameters_.extensions.push_back(
490 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700491 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000493
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200495 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700496 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800497 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000498
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000499 // Ensure extension is set properly.
500 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700501 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700502 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
504 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
505 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000506
solenberg7add0582015-11-20 09:59:34 -0800507 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200508 EXPECT_TRUE(
509 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
511 call_.GetAudioSendStream(kSsrcY));
512 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
513 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
514 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000515
516 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200517 send_parameters_.codecs.push_back(kPcmuCodec);
518 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700519 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
521 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000522 }
523
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000524 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700525 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000527 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800528 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000529
530 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700531 recv_parameters_.extensions.push_back(
532 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800533 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800534 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000535
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000536 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800537 recv_parameters_.extensions.clear();
538 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800539 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000540
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000541 // Ensure extension is set properly.
542 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700543 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800544 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800545 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
546 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
547 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000548
solenberg7add0582015-11-20 09:59:34 -0800549 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800550 EXPECT_TRUE(AddRecvStream(kSsrcY));
551 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
552 call_.GetAudioReceiveStream(kSsrcY));
553 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
554 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
555 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000556
557 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800558 recv_parameters_.extensions.clear();
559 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800560 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
561 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000562 }
563
solenberg85a04962015-10-27 03:35:21 -0700564 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
565 webrtc::AudioSendStream::Stats stats;
566 stats.local_ssrc = 12;
567 stats.bytes_sent = 345;
568 stats.packets_sent = 678;
569 stats.packets_lost = 9012;
570 stats.fraction_lost = 34.56f;
571 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100572 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700573 stats.ext_seqnum = 789;
574 stats.jitter_ms = 12;
575 stats.rtt_ms = 345;
576 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100577 stats.apm_statistics.delay_median_ms = 234;
578 stats.apm_statistics.delay_standard_deviation_ms = 567;
579 stats.apm_statistics.echo_return_loss = 890;
580 stats.apm_statistics.echo_return_loss_enhancement = 1234;
581 stats.apm_statistics.residual_echo_likelihood = 0.432f;
582 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100583 stats.ana_statistics.bitrate_action_counter = 321;
584 stats.ana_statistics.channel_action_counter = 432;
585 stats.ana_statistics.dtx_action_counter = 543;
586 stats.ana_statistics.fec_action_counter = 654;
587 stats.ana_statistics.frame_length_increase_counter = 765;
588 stats.ana_statistics.frame_length_decrease_counter = 876;
589 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700590 stats.typing_noise_detected = true;
591 return stats;
592 }
593 void SetAudioSendStreamStats() {
594 for (auto* s : call_.GetAudioSendStreams()) {
595 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200596 }
solenberg85a04962015-10-27 03:35:21 -0700597 }
solenberg566ef242015-11-06 15:34:49 -0800598 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
599 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700600 const auto stats = GetAudioSendStreamStats();
601 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
602 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
603 EXPECT_EQ(info.packets_sent, stats.packets_sent);
604 EXPECT_EQ(info.packets_lost, stats.packets_lost);
605 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
606 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800607 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700608 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
609 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
610 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
611 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100612 EXPECT_EQ(info.apm_statistics.delay_median_ms,
613 stats.apm_statistics.delay_median_ms);
614 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
615 stats.apm_statistics.delay_standard_deviation_ms);
616 EXPECT_EQ(info.apm_statistics.echo_return_loss,
617 stats.apm_statistics.echo_return_loss);
618 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
619 stats.apm_statistics.echo_return_loss_enhancement);
620 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
621 stats.apm_statistics.residual_echo_likelihood);
622 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
623 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700624 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
625 stats.ana_statistics.bitrate_action_counter);
626 EXPECT_EQ(info.ana_statistics.channel_action_counter,
627 stats.ana_statistics.channel_action_counter);
628 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
629 stats.ana_statistics.dtx_action_counter);
630 EXPECT_EQ(info.ana_statistics.fec_action_counter,
631 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700632 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
633 stats.ana_statistics.frame_length_increase_counter);
634 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
635 stats.ana_statistics.frame_length_decrease_counter);
636 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
637 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800638 EXPECT_EQ(info.typing_noise_detected,
639 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700640 }
641
642 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
643 webrtc::AudioReceiveStream::Stats stats;
644 stats.remote_ssrc = 123;
645 stats.bytes_rcvd = 456;
646 stats.packets_rcvd = 768;
647 stats.packets_lost = 101;
648 stats.fraction_lost = 23.45f;
649 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100650 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700651 stats.ext_seqnum = 678;
652 stats.jitter_ms = 901;
653 stats.jitter_buffer_ms = 234;
654 stats.jitter_buffer_preferred_ms = 567;
655 stats.delay_estimate_ms = 890;
656 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700657 stats.total_samples_received = 5678901;
658 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200659 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200660 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100661 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700662 stats.expand_rate = 5.67f;
663 stats.speech_expand_rate = 8.90f;
664 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200665 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700666 stats.accelerate_rate = 4.56f;
667 stats.preemptive_expand_rate = 7.89f;
668 stats.decoding_calls_to_silence_generator = 12;
669 stats.decoding_calls_to_neteq = 345;
670 stats.decoding_normal = 67890;
671 stats.decoding_plc = 1234;
672 stats.decoding_cng = 5678;
673 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700674 stats.decoding_muted_output = 3456;
675 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200676 return stats;
677 }
678 void SetAudioReceiveStreamStats() {
679 for (auto* s : call_.GetAudioReceiveStreams()) {
680 s->SetStats(GetAudioReceiveStreamStats());
681 }
682 }
683 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700684 const auto stats = GetAudioReceiveStreamStats();
685 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
686 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200687 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
688 stats.packets_rcvd);
689 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
690 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700691 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
692 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800693 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
695 stats.ext_seqnum);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
698 stats.jitter_buffer_ms);
699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700700 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
702 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700703 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700704 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
705 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200706 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200707 EXPECT_EQ(info.jitter_buffer_delay_seconds,
708 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100709 EXPECT_EQ(info.jitter_buffer_emitted_count,
710 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700711 EXPECT_EQ(info.expand_rate, stats.expand_rate);
712 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
713 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200714 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700715 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
716 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200717 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700718 stats.decoding_calls_to_silence_generator);
719 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
720 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
721 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
722 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
723 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700724 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700725 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200726 }
hbos1acfbd22016-11-17 23:43:29 -0800727 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
728 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
729 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
730 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
731 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
732 codec.ToCodecParameters());
733 }
734 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
735 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
736 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
737 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
738 codec.ToCodecParameters());
739 }
740 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200741
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100742 void VerifyGainControlEnabledCorrectly() {
743 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
744 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
745 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
746 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
747 }
748
749 void VerifyGainControlDefaultSettings() {
750 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
751 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
752 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
753 }
754
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200755 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100756 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200757 }
758
peah8271d042016-11-22 07:24:52 -0800759 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100760 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800761 }
762
Sam Zackrissonba502232019-01-04 10:36:48 +0100763 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100764 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100765 }
766
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100768 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700769 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700770 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800771 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200772 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700773 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700774 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioSendParameters send_parameters_;
776 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800777 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700778 webrtc::AudioProcessing::Config apm_config_;
779
stefanba4c0e42016-02-04 04:12:24 -0800780 private:
781 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782};
783
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100785TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700786 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787}
788
solenberg31fec402016-05-06 02:13:12 -0700789// Test that we can add a send stream and that it has the correct defaults.
790TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
791 EXPECT_TRUE(SetupChannel());
792 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800793 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
794 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
795 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700796 EXPECT_EQ("", config.rtp.c_name);
797 EXPECT_EQ(0u, config.rtp.extensions.size());
798 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
799 config.send_transport);
800}
801
802// Test that we can add a receive stream and that it has the correct defaults.
803TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
804 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800805 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700806 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800807 GetRecvStreamConfig(kSsrcX);
808 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700809 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
810 EXPECT_FALSE(config.rtp.transport_cc);
811 EXPECT_EQ(0u, config.rtp.extensions.size());
812 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
813 config.rtcp_send_transport);
814 EXPECT_EQ("", config.sync_group);
815}
816
stefanba4c0e42016-02-04 04:12:24 -0800817TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700818 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800819 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100820 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800821 if (codec.name == "opus") {
822 EXPECT_TRUE(HasTransportCc(codec));
823 opus_found = true;
824 }
825 }
826 EXPECT_TRUE(opus_found);
827}
828
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829// Test that we set our inbound codecs properly, including changing PT.
830TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200832 cricket::AudioRecvParameters parameters;
833 parameters.codecs.push_back(kIsacCodec);
834 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800835 parameters.codecs.push_back(kTelephoneEventCodec1);
836 parameters.codecs.push_back(kTelephoneEventCodec2);
837 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200838 parameters.codecs[2].id = 126;
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700841 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
842 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
843 {{0, {"PCMU", 8000, 1}},
844 {106, {"ISAC", 16000, 1}},
845 {126, {"telephone-event", 8000, 1}},
846 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
849// Test that we fail to set an unknown inbound codec.
850TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700851 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 cricket::AudioRecvParameters parameters;
853 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700854 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we fail if we have duplicate types in the inbound list.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kCn16000Codec);
864 parameters.codecs[1].id = kIsacCodec.id;
865 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866}
867
868// Test that we can decode OPUS without stereo parameters.
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 cricket::AudioRecvParameters parameters;
872 parameters.codecs.push_back(kIsacCodec);
873 parameters.codecs.push_back(kPcmuCodec);
874 parameters.codecs.push_back(kOpusCodec);
875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800876 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700877 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
878 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
879 {{0, {"PCMU", 8000, 1}},
880 {103, {"ISAC", 16000, 1}},
881 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882}
883
884// Test that we can decode OPUS with stereo = 0.
885TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700886 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 cricket::AudioRecvParameters parameters;
888 parameters.codecs.push_back(kIsacCodec);
889 parameters.codecs.push_back(kPcmuCodec);
890 parameters.codecs.push_back(kOpusCodec);
891 parameters.codecs[2].params["stereo"] = "0";
892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800893 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700894 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
895 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
896 {{0, {"PCMU", 8000, 1}},
897 {103, {"ISAC", 16000, 1}},
898 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899}
900
901// Test that we can decode OPUS with stereo = 1.
902TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700903 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 cricket::AudioRecvParameters parameters;
905 parameters.codecs.push_back(kIsacCodec);
906 parameters.codecs.push_back(kPcmuCodec);
907 parameters.codecs.push_back(kOpusCodec);
908 parameters.codecs[2].params["stereo"] = "1";
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700911 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
912 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
913 {{0, {"PCMU", 8000, 1}},
914 {103, {"ISAC", 16000, 1}},
915 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916}
917
918// Test that changes to recv codecs are applied to all streams.
919TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700920 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 cricket::AudioRecvParameters parameters;
922 parameters.codecs.push_back(kIsacCodec);
923 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800924 parameters.codecs.push_back(kTelephoneEventCodec1);
925 parameters.codecs.push_back(kTelephoneEventCodec2);
926 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200927 parameters.codecs[2].id = 126;
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700929 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
930 EXPECT_TRUE(AddRecvStream(ssrc));
931 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
932 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
933 {{0, {"PCMU", 8000, 1}},
934 {106, {"ISAC", 16000, 1}},
935 {126, {"telephone-event", 8000, 1}},
936 {107, {"telephone-event", 32000, 1}}})));
937 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
940TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700941 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 cricket::AudioRecvParameters parameters;
943 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800944 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
solenberg2100c0b2017-03-01 11:29:29 -0800947 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200948 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800949 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
952// Test that we can apply the same set of codecs again while playing.
953TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 cricket::AudioRecvParameters parameters;
956 parameters.codecs.push_back(kIsacCodec);
957 parameters.codecs.push_back(kCn16000Codec);
958 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700959 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
deadbeefcb383672017-04-26 16:28:42 -0700962 // Remapping a payload type to a different codec should fail.
963 parameters.codecs[0] = kOpusCodec;
964 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800966 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
969// Test that we can add a codec while playing.
970TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200972 cricket::AudioRecvParameters parameters;
973 parameters.codecs.push_back(kIsacCodec);
974 parameters.codecs.push_back(kCn16000Codec);
975 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700976 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 parameters.codecs.push_back(kOpusCodec);
979 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800980 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
deadbeefcb383672017-04-26 16:28:42 -0700983// Test that we accept adding the same codec with a different payload type.
984// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
985TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
986 EXPECT_TRUE(SetupRecvStream());
987 cricket::AudioRecvParameters parameters;
988 parameters.codecs.push_back(kIsacCodec);
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
990
991 ++parameters.codecs[0].id;
992 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
993}
994
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700996 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998 // Test that when autobw is enabled, bitrate is kept as the default
999 // value. autobw is enabled for the following tests because the target
1000 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001003 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
ossu20a4b3f2017-04-27 02:08:52 -07001008 // opus, default bitrate == 32000 in mono.
1009 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010}
1011
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001013 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001016 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1017 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001018 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001021 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1022 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1023 // Rates above the max (510000) should be capped.
1024 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025}
1026
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001027TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001028 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001029
1030 // Test that we can only set a maximum bitrate for a fixed-rate codec
1031 // if it's bigger than the fixed rate.
1032
1033 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001034 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1035 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001041}
1042
1043TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001044 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 const int kDesiredBitrate = 128000;
1046 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001047 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001048 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001049 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001050
Yves Gerey665174f2018-06-19 15:03:05 +02001051 EXPECT_TRUE(
1052 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001053
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001055}
1056
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057// Test that bitrate cannot be set for CBR codecs.
1058// Bitrate is ignored if it is higher than the fixed bitrate.
1059// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001060TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001061 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062
1063 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001064 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001066
1067 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001068 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001070
1071 send_parameters_.max_bandwidth_bps = 128;
1072 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001073 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074}
1075
skvlade0d46372016-04-07 22:59:22 -07001076// Test that the per-stream bitrate limit and the global
1077// bitrate limit both apply.
1078TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1079 EXPECT_TRUE(SetupSendStream());
1080
ossu20a4b3f2017-04-27 02:08:52 -07001081 // opus, default bitrate == 32000.
1082 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001083 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1084 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1085 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1086
1087 // CBR codecs allow both maximums to exceed the bitrate.
1088 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1089 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1090 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1092
1093 // CBR codecs don't allow per stream maximums to be too low.
1094 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1095 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1096}
1097
1098// Test that an attempt to set RtpParameters for a stream that does not exist
1099// fails.
1100TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1101 EXPECT_TRUE(SetupChannel());
1102 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001103 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001104 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001105
1106 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_FALSE(
1108 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001109}
1110
1111TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001113 // This test verifies that setting RtpParameters succeeds only if
1114 // the structure contains exactly one encoding.
1115 // TODO(skvlad): Update this test when we start supporting setting parameters
1116 // for each encoding individually.
1117
1118 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001119 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001120 // Two or more encodings should result in failure.
1121 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001122 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001123 // Zero encodings should also fail.
1124 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001125 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001126}
1127
1128// Changing the SSRC through RtpParameters is not allowed.
1129TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1130 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001132 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001133 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001134}
1135
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001136// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001137// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001138TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1139 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001140 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001141 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001142 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 ASSERT_EQ(1u, parameters.encodings.size());
1145 ASSERT_TRUE(parameters.encodings[0].active);
1146 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001147 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001148 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001149
1150 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001151 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001152 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001153 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001154 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001155 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001156}
1157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158// Test that SetRtpSendParameters configures the correct encoding channel for
1159// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001160TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1161 SetupForMultiSendStream();
1162 // Create send streams.
1163 for (uint32_t ssrc : kSsrcs4) {
1164 EXPECT_TRUE(
1165 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1166 }
1167 // Configure one stream to be limited by the stream config, another to be
1168 // limited by the global max, and the third one with no per-stream limit
1169 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001170 SetGlobalMaxBitrate(kOpusCodec, 32000);
1171 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1172 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1174
ossu20a4b3f2017-04-27 02:08:52 -07001175 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1176 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1177 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001178
1179 // Remove the global cap; the streams should switch to their respective
1180 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001181 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001182 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1183 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1184 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001185}
1186
Tim Haloun648d28a2018-10-18 16:52:22 -07001187// RTCRtpEncodingParameters.network_priority must be one of a few values
1188// derived from the default priority, corresponding to very-low, low, medium,
1189// or high.
1190TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1191 EXPECT_TRUE(SetupSendStream());
1192 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1193 EXPECT_EQ(1UL, parameters.encodings.size());
1194 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1195 parameters.encodings[0].network_priority);
1196
1197 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1198 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1199 for (auto it : good_values) {
1200 parameters.encodings[0].network_priority = it;
1201 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1202 }
1203 for (auto it : bad_values) {
1204 parameters.encodings[0].network_priority = it;
1205 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1206 }
1207}
1208
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209// Test that GetRtpSendParameters returns the currently configured codecs.
1210TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001211 EXPECT_TRUE(SetupSendStream());
1212 cricket::AudioSendParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001215 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001216
solenberg2100c0b2017-03-01 11:29:29 -08001217 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001219 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1220 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221}
1222
Florent Castellidacec712018-05-24 16:24:21 +02001223// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1224TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1225 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1226 params.cname = "rtcpcname";
1227 EXPECT_TRUE(SetupSendStream(params));
1228
1229 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1230 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1231}
1232
Florent Castelliabe301f2018-06-12 18:33:49 +02001233TEST_F(WebRtcVoiceEngineTestFake,
1234 DetectRtpSendParameterHeaderExtensionsChange) {
1235 EXPECT_TRUE(SetupSendStream());
1236
1237 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1238 rtp_parameters.header_extensions.emplace_back();
1239
1240 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1241
1242 webrtc::RTCError result =
1243 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1244 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1245}
1246
deadbeefcb443432016-12-12 11:12:36 -08001247// Test that GetRtpSendParameters returns an SSRC.
1248TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1249 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001250 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001251 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001252 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001253}
1254
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001255// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001256TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257 EXPECT_TRUE(SetupSendStream());
1258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kIsacCodec);
1260 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001261 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001262
solenberg2100c0b2017-03-01 11:29:29 -08001263 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
1265 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001266 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001267
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001268 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001269 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1270 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001271}
1272
minyuececec102017-03-27 13:04:25 -07001273// Test that max_bitrate_bps in send stream config gets updated correctly when
1274// SetRtpSendParameters is called.
1275TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1276 webrtc::test::ScopedFieldTrials override_field_trials(
1277 "WebRTC-Audio-SendSideBwe/Enabled/");
1278 EXPECT_TRUE(SetupSendStream());
1279 cricket::AudioSendParameters send_parameters;
1280 send_parameters.codecs.push_back(kOpusCodec);
1281 SetSendParameters(send_parameters);
1282
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1284 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1285 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1286
1287 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001288 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001289 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001290
1291 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1292 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1293}
1294
Seth Hampson24722b32017-12-22 09:36:42 -08001295// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1296// a value <= 0, setting the parameters returns false.
1297TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1298 EXPECT_TRUE(SetupSendStream());
1299 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1300 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1301 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1302 rtp_parameters.encodings[0].bitrate_priority);
1303
1304 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001305 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001306 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001307 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001308}
1309
1310// Test that the bitrate_priority in the send stream config gets updated when
1311// SetRtpSendParameters is set for the VoiceMediaChannel.
1312TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1313 EXPECT_TRUE(SetupSendStream());
1314 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1315
1316 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1317 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1318 rtp_parameters.encodings[0].bitrate_priority);
1319 double new_bitrate_priority = 2.0;
1320 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001321 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001322
1323 // The priority should get set for both the audio channel's rtp parameters
1324 // and the audio send stream's audio config.
1325 EXPECT_EQ(
1326 new_bitrate_priority,
1327 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1328 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1329}
1330
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001331// Test that GetRtpReceiveParameters returns the currently configured codecs.
1332TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1333 EXPECT_TRUE(SetupRecvStream());
1334 cricket::AudioRecvParameters parameters;
1335 parameters.codecs.push_back(kIsacCodec);
1336 parameters.codecs.push_back(kPcmuCodec);
1337 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1338
1339 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001340 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001341 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1342 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1343 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1344}
1345
deadbeefcb443432016-12-12 11:12:36 -08001346// Test that GetRtpReceiveParameters returns an SSRC.
1347TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1348 EXPECT_TRUE(SetupRecvStream());
1349 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001350 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001351 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001352 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001353}
1354
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001355// Test that if we set/get parameters multiple times, we get the same results.
1356TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1357 EXPECT_TRUE(SetupRecvStream());
1358 cricket::AudioRecvParameters parameters;
1359 parameters.codecs.push_back(kIsacCodec);
1360 parameters.codecs.push_back(kPcmuCodec);
1361 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1362
1363 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001364 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365
1366 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001367 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001368
1369 // ... And this shouldn't change the params returned by
1370 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001371 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1372 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001373}
1374
deadbeef3bc15102017-04-20 19:25:07 -07001375// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1376// aren't signaled. It should return an empty "RtpEncodingParameters" when
1377// configured to receive an unsignaled stream and no packets have been received
1378// yet, and start returning the SSRC once a packet has been received.
1379TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1380 ASSERT_TRUE(SetupChannel());
1381 // Call necessary methods to configure receiving a default stream as
1382 // soon as it arrives.
1383 cricket::AudioRecvParameters parameters;
1384 parameters.codecs.push_back(kIsacCodec);
1385 parameters.codecs.push_back(kPcmuCodec);
1386 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1387
1388 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1389 // stream. Should return nothing.
1390 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1391
1392 // Set a sink for an unsignaled stream.
1393 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1394 // Value of "0" means "unsignaled stream".
1395 channel_->SetRawAudioSink(0, std::move(fake_sink));
1396
1397 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1398 // in this method means "unsignaled stream".
1399 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1400 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1401 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1402
1403 // Receive PCMU packet (SSRC=1).
1404 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1405
1406 // The |ssrc| member should still be unset.
1407 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1408 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1409 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1410}
1411
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412// Test that we apply codecs properly.
1413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kIsacCodec);
1417 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001418 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001420 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1423 EXPECT_EQ(96, send_codec_spec.payload_type);
1424 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1425 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1426 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001427 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001428 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429}
1430
ossu20a4b3f2017-04-27 02:08:52 -07001431// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1432// AudioSendStream.
1433TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kIsacCodec);
1437 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001438 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 parameters.codecs[0].id = 96;
1440 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001441 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001443 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001444 // Calling SetSendCodec again with same codec which is already set.
1445 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001448}
1449
ossu20a4b3f2017-04-27 02:08:52 -07001450// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1451// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001452
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001453// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 0;
1459 parameters.codecs[0].clockrate = 50000;
1460 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001463// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 0;
1469 parameters.codecs[0].channels = 0;
1470 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471}
1472
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001473// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].bitrate = 0;
1479 parameters.codecs[0].channels = 0;
1480 parameters.codecs[0].params["stereo"] = "1";
1481 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
1484// Test that if channel is 1 for opus and there's no stereo, we fail.
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].channels = 1;
1491 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001492}
1493
1494// Test that if channel is 1 for opus and stereo=0, we fail.
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001496 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001497 cricket::AudioSendParameters parameters;
1498 parameters.codecs.push_back(kOpusCodec);
1499 parameters.codecs[0].bitrate = 0;
1500 parameters.codecs[0].channels = 1;
1501 parameters.codecs[0].params["stereo"] = "0";
1502 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001503}
1504
1505// Test that if channel is 1 for opus and stereo=1, we fail.
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001507 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001508 cricket::AudioSendParameters parameters;
1509 parameters.codecs.push_back(kOpusCodec);
1510 parameters.codecs[0].bitrate = 0;
1511 parameters.codecs[0].channels = 1;
1512 parameters.codecs[0].params["stereo"] = "1";
1513 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001523 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 0;
1532 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001543 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001546 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001547
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001549 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001550 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001551}
1552
ossu20a4b3f2017-04-27 02:08:52 -07001553// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001555 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kOpusCodec);
1558 parameters.codecs[0].bitrate = 0;
1559 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001561 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
ossu20a4b3f2017-04-27 02:08:52 -07001564// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001570 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001573 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001574
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001577 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001578}
1579
ossu20a4b3f2017-04-27 02:08:52 -07001580// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001587 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1588 EXPECT_EQ(111, spec.payload_type);
1589 EXPECT_EQ(96000, spec.target_bitrate_bps);
1590 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001591 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001592 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
ossu20a4b3f2017-04-27 02:08:52 -07001595// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].bitrate = 30000;
1601 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001603 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
ossu20a4b3f2017-04-27 02:08:52 -07001606// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters parameters;
1610 parameters.codecs.push_back(kOpusCodec);
1611 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001613 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
ossu20a4b3f2017-04-27 02:08:52 -07001616// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kOpusCodec);
1621 parameters.codecs[0].bitrate = 30000;
1622 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001624 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001625}
1626
stefan13f1a0a2016-11-30 07:22:58 -08001627TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1628 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1629 200000);
1630}
1631
1632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1633 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1634}
1635
1636TEST_F(WebRtcVoiceEngineTestFake,
1637 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1638 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1639}
1640
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1642 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1643}
1644
Yves Gerey665174f2018-06-19 15:03:05 +02001645TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001646 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1647 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001648 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001649 // Setting max bitrate should keep previous min bitrate
1650 // Setting max bitrate should not reset start bitrate.
1651 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1652 SetSdpBitrateParameters(
1653 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1654 Field(&BitrateConstraints::start_bitrate_bps, -1),
1655 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001656 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001657}
1658
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001659// Test that we can enable NACK with opus as callee.
1660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 cricket::AudioSendParameters parameters;
1663 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001664 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1665 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001667 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001668 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001669 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001670
Yves Gerey665174f2018-06-19 15:03:05 +02001671 EXPECT_TRUE(
1672 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001673}
1674
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675// Test that we can enable NACK on receive streams.
1676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters parameters;
1680 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001681 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1682 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001684 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001685 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686}
1687
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688// Test that we can disable NACK on receive streams.
1689TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001690 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001691 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 cricket::AudioSendParameters parameters;
1693 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001694 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1695 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs.clear();
1700 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001702 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703}
1704
1705// Test that NACK is enabled on a new receive stream.
1706TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001707 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 cricket::AudioSendParameters parameters;
1709 parameters.codecs.push_back(kIsacCodec);
1710 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001711 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1712 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
solenberg2100c0b2017-03-01 11:29:29 -08001715 EXPECT_TRUE(AddRecvStream(kSsrcY));
1716 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1717 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1718 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719}
1720
stefanba4c0e42016-02-04 04:12:24 -08001721TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001723 cricket::AudioSendParameters send_parameters;
1724 send_parameters.codecs.push_back(kOpusCodec);
1725 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001727
1728 cricket::AudioRecvParameters recv_parameters;
1729 recv_parameters.codecs.push_back(kIsacCodec);
1730 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001731 EXPECT_TRUE(AddRecvStream(kSsrcX));
1732 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001733 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001734 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001735
ossudedfd282016-06-14 07:12:39 -07001736 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001738 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001739 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001740 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001741}
1742
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001743// Test that we can switch back and forth between Opus and ISAC with CN.
1744TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001745 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 cricket::AudioSendParameters opus_parameters;
1748 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001750 {
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(111, spec.payload_type);
1753 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters isac_parameters;
1757 isac_parameters.codecs.push_back(kIsacCodec);
1758 isac_parameters.codecs.push_back(kCn16000Codec);
1759 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001761 {
ossu20a4b3f2017-04-27 02:08:52 -07001762 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1763 EXPECT_EQ(103, spec.payload_type);
1764 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001765 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001768 {
ossu20a4b3f2017-04-27 02:08:52 -07001769 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1770 EXPECT_EQ(111, spec.payload_type);
1771 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001772 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001773}
1774
1775// Test that we handle various ways of specifying bitrate.
1776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001777 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001778 cricket::AudioSendParameters parameters;
1779 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 {
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(103, spec.payload_type);
1784 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1785 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787
Yves Gerey665174f2018-06-19 15:03:05 +02001788 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001790 {
ossu20a4b3f2017-04-27 02:08:52 -07001791 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1792 EXPECT_EQ(103, spec.payload_type);
1793 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1794 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001795 }
Yves Gerey665174f2018-06-19 15:03:05 +02001796 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001798 {
ossu20a4b3f2017-04-27 02:08:52 -07001799 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1800 EXPECT_EQ(103, spec.payload_type);
1801 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1802 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001803 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001804
Yves Gerey665174f2018-06-19 15:03:05 +02001805 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001807 {
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(0, spec.payload_type);
1810 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1811 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001812 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813
Yves Gerey665174f2018-06-19 15:03:05 +02001814 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 {
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(0, spec.payload_type);
1819 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1820 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001821 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001822
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001824 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001826 {
ossu20a4b3f2017-04-27 02:08:52 -07001827 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1828 EXPECT_EQ(111, spec.payload_type);
1829 EXPECT_STREQ("opus", spec.format.name.c_str());
1830 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832}
1833
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001834// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
1838 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001839}
1840
1841// Test that we can set send codecs even with telephone-event codec as the first
1842// one on the list.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001846 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kIsacCodec);
1848 parameters.codecs.push_back(kPcmuCodec);
1849 parameters.codecs[0].id = 98; // DTMF
1850 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001852 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1853 EXPECT_EQ(96, spec.payload_type);
1854 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001855 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001856 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001857}
1858
Harald Alvestranda1f66612018-02-21 11:24:23 +01001859// Test that CanInsertDtmf() is governed by the send flag
1860TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1861 EXPECT_TRUE(SetupSendStream());
1862 cricket::AudioSendParameters parameters;
1863 parameters.codecs.push_back(kTelephoneEventCodec1);
1864 parameters.codecs.push_back(kPcmuCodec);
1865 parameters.codecs[0].id = 98; // DTMF
1866 parameters.codecs[1].id = 96;
1867 SetSendParameters(parameters);
1868 EXPECT_FALSE(channel_->CanInsertDtmf());
1869 SetSend(true);
1870 EXPECT_TRUE(channel_->CanInsertDtmf());
1871 SetSend(false);
1872 EXPECT_FALSE(channel_->CanInsertDtmf());
1873}
1874
solenberg31642aa2016-03-14 08:00:37 -07001875// Test that payload type range is limited for telephone-event codec.
1876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001877 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001878 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001879 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001880 parameters.codecs.push_back(kIsacCodec);
1881 parameters.codecs[0].id = 0; // DTMF
1882 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001884 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001885 EXPECT_TRUE(channel_->CanInsertDtmf());
1886 parameters.codecs[0].id = 128; // DTMF
1887 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1888 EXPECT_FALSE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001890 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001891 EXPECT_TRUE(channel_->CanInsertDtmf());
1892 parameters.codecs[0].id = -1; // DTMF
1893 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1894 EXPECT_FALSE(channel_->CanInsertDtmf());
1895}
1896
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001897// Test that we can set send codecs even with CN codec as the first
1898// one on the list.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kCn16000Codec);
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
1905 parameters.codecs[0].id = 98; // wideband CN
1906 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001907 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001908 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1909 EXPECT_EQ(96, send_codec_spec.payload_type);
1910 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001911 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001912}
1913
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001914// Test that we set VAD and DTMF types correctly as caller.
1915TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001916 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001917 cricket::AudioSendParameters parameters;
1918 parameters.codecs.push_back(kIsacCodec);
1919 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs.push_back(kCn16000Codec);
1922 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001923 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 parameters.codecs[0].id = 96;
1925 parameters.codecs[2].id = 97; // wideband CN
1926 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001927 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001928 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1929 EXPECT_EQ(96, send_codec_spec.payload_type);
1930 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001931 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001932 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001933 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001934 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935}
1936
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001937// Test that we set VAD and DTMF types correctly as callee.
1938TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001939 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 cricket::AudioSendParameters parameters;
1941 parameters.codecs.push_back(kIsacCodec);
1942 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001943 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs.push_back(kCn16000Codec);
1945 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001946 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0].id = 96;
1948 parameters.codecs[2].id = 97; // wideband CN
1949 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001951 EXPECT_TRUE(
1952 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001953
ossu20a4b3f2017-04-27 02:08:52 -07001954 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1955 EXPECT_EQ(96, send_codec_spec.payload_type);
1956 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001957 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001958 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001959 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001960 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001961}
1962
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001963// Test that we only apply VAD if we have a CN codec that matches the
1964// send codec clockrate.
1965TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001966 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs.push_back(kIsacCodec);
1970 parameters.codecs.push_back(kCn16000Codec);
1971 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001973 {
ossu20a4b3f2017-04-27 02:08:52 -07001974 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1975 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001976 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001977 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001978 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001979 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 {
ossu20a4b3f2017-04-27 02:08:52 -07001983 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1984 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001985 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001986 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001987 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001988 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001989 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001990 {
ossu20a4b3f2017-04-27 02:08:52 -07001991 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1992 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001993 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001994 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001995 }
Brave Yao5225dd82015-03-26 07:39:19 +08001996 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001999 {
ossu20a4b3f2017-04-27 02:08:52 -07002000 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2001 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002002 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002003 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002004}
2005
2006// Test that we perform case-insensitive matching of codec names.
2007TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
2010 parameters.codecs.push_back(kIsacCodec);
2011 parameters.codecs.push_back(kPcmuCodec);
2012 parameters.codecs.push_back(kCn16000Codec);
2013 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002014 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002015 parameters.codecs[0].name = "iSaC";
2016 parameters.codecs[0].id = 96;
2017 parameters.codecs[2].id = 97; // wideband CN
2018 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002019 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002020 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2021 EXPECT_EQ(96, send_codec_spec.payload_type);
2022 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002023 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002024 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002025 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002026 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027}
2028
stefanba4c0e42016-02-04 04:12:24 -08002029class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2030 public:
2031 WebRtcVoiceEngineWithSendSideBweTest()
2032 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2033};
2034
2035TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2036 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002037 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2038 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002039 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002040 "uri", &RtpExtension::uri,
2041 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002042}
2043
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002044// Test support for audio level header extension.
2045TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002046 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002047}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002048TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002049 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002051
solenbergd4adce42016-11-17 06:26:52 -08002052// Test support for transport sequence number header extension.
2053TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2054 TestSetSendRtpHeaderExtensions(
2055 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002056}
solenbergd4adce42016-11-17 06:26:52 -08002057TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2058 TestSetRecvRtpHeaderExtensions(
2059 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060}
2061
solenberg1ac56142015-10-13 03:58:19 -07002062// Test that we can create a channel and start sending on it.
2063TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSendParameters(send_parameters_);
2066 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002067 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002068 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002070}
2071
2072// Test that a channel will send if and only if it has a source and is enabled
2073// for sending.
2074TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002075 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002076 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002077 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2080 SetAudioSend(kSsrcX, true, &fake_source_);
2081 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2082 SetAudioSend(kSsrcX, true, nullptr);
2083 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002084}
2085
solenberg94218532016-06-16 10:53:22 -07002086// Test that a channel is muted/unmuted.
2087TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2088 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002089 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2091 SetAudioSend(kSsrcX, true, nullptr);
2092 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2093 SetAudioSend(kSsrcX, false, nullptr);
2094 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002095}
2096
solenberg6d6e7c52016-04-13 09:07:30 -07002097// Test that SetSendParameters() does not alter a stream's send state.
2098TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2099 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002101
2102 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002103 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105
2106 // Changing RTP header extensions will recreate the AudioSendStream.
2107 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002108 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002109 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002110 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002111
2112 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002115
2116 // Changing RTP header extensions will recreate the AudioSendStream.
2117 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002118 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002120}
2121
solenberg1ac56142015-10-13 03:58:19 -07002122// Test that we can create a channel and start playing out on it.
2123TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002124 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002125 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002126 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002127 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002128 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130}
2131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132// Test that we can add and remove send streams.
2133TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2134 SetupForMultiSendStream();
2135
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002137 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138
solenbergc96df772015-10-21 13:01:53 -07002139 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002140 EXPECT_TRUE(
2141 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002142 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002144 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 }
tfarina5237aaf2015-11-10 23:44:30 -08002146 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147
solenbergc96df772015-10-21 13:01:53 -07002148 // Delete the send streams.
2149 for (uint32_t ssrc : kSsrcs4) {
2150 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002151 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002152 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
solenbergc96df772015-10-21 13:01:53 -07002154 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155}
2156
2157// Test SetSendCodecs correctly configure the codecs in all send streams.
2158TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2159 SetupForMultiSendStream();
2160
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002162 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002163 EXPECT_TRUE(
2164 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 }
2166
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs.push_back(kIsacCodec);
2170 parameters.codecs.push_back(kCn16000Codec);
2171 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173
2174 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002175 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002176 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2177 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002178 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2179 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002180 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002181 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002182 }
2183
minyue7a973442016-10-20 03:27:12 -07002184 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002185 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002186 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002188 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2189 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002190 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2191 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002192 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193 }
2194}
2195
2196// Test we can SetSend on all send streams correctly.
2197TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2198 SetupForMultiSendStream();
2199
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002200 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002201 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002202 EXPECT_TRUE(
2203 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002204 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002206 }
2207
2208 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002209 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002210 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002212 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 }
2214
2215 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002216 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002217 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002218 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002219 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 }
2221}
2222
2223// Test we can set the correct statistics on all send streams.
2224TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2225 SetupForMultiSendStream();
2226
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002228 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002229 EXPECT_TRUE(
2230 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231 }
solenberg85a04962015-10-27 03:35:21 -07002232
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002233 // Create a receive stream to check that none of the send streams end up in
2234 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002235 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002236
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002237 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002238 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002239 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002240 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002241
solenberg85a04962015-10-27 03:35:21 -07002242 // Check stats for the added streams.
2243 {
2244 cricket::VoiceMediaInfo info;
2245 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002246
solenberg85a04962015-10-27 03:35:21 -07002247 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002248 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002249 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002250 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002251 }
hbos1acfbd22016-11-17 23:43:29 -08002252 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002253
2254 // We have added one receive stream. We should see empty stats.
2255 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002256 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002257 }
solenberg1ac56142015-10-13 03:58:19 -07002258
solenberg2100c0b2017-03-01 11:29:29 -08002259 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002260 {
2261 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002263 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002264 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002265 EXPECT_EQ(0u, info.receivers.size());
2266 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002267
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002268 // Deliver a new packet - a default receive stream should be created and we
2269 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002270 {
2271 cricket::VoiceMediaInfo info;
2272 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2273 SetAudioReceiveStreamStats();
2274 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002275 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002276 EXPECT_EQ(1u, info.receivers.size());
2277 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002278 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002279 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002280}
2281
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282// Test that we can add and remove receive streams, and do proper send/playout.
2283// We can receive on multiple streams while sending one stream.
2284TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002285 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002286
solenberg1ac56142015-10-13 03:58:19 -07002287 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002288 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002289 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290
solenberg1ac56142015-10-13 03:58:19 -07002291 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002293 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
solenberg1ac56142015-10-13 03:58:19 -07002296 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298
2299 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2301 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2302 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
2304 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002305 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307
2308 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002309 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2311 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312
aleloi84ef6152016-08-04 05:28:21 -07002313 // Restart playout and make sure recv streams are played out.
2314 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2316 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
aleloi84ef6152016-08-04 05:28:21 -07002318 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2320 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321}
2322
wu@webrtc.org97077a32013-10-25 21:18:33 +00002323TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002324 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002325 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002326 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002327 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002328 const auto& agc_config = apm_config_.gain_controller1;
2329
2330 // Ensure default options.
2331 VerifyGainControlEnabledCorrectly();
2332 VerifyGainControlDefaultSettings();
2333
2334 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002335 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002336 EXPECT_FALSE(agc_config.enabled);
2337 send_parameters_.options.auto_gain_control = absl::nullopt;
2338
2339 send_parameters_.options.tx_agc_target_dbov = 5;
2340 SetSendParameters(send_parameters_);
2341 EXPECT_EQ(5, agc_config.target_level_dbfs);
2342 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2343
2344 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(10, agc_config.compression_gain_db);
2347 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2348
2349 send_parameters_.options.tx_agc_limiter = false;
2350 SetSendParameters(send_parameters_);
2351 EXPECT_FALSE(agc_config.enable_limiter);
2352 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2353
2354 SetSendParameters(send_parameters_);
2355 // Expect all options to have been preserved.
2356 EXPECT_FALSE(agc_config.enabled);
2357 EXPECT_EQ(5, agc_config.target_level_dbfs);
2358 EXPECT_EQ(10, agc_config.compression_gain_db);
2359 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002360}
2361
minyue6b825df2016-10-31 04:08:32 -07002362TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2363 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002364 send_parameters_.options.audio_network_adaptor = true;
2365 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002366 SetSendParameters(send_parameters_);
2367 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002368 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002369}
2370
2371TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2372 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002373 send_parameters_.options.audio_network_adaptor = true;
2374 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002375 SetSendParameters(send_parameters_);
2376 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002377 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002378 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002379 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002380 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002381 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002382}
2383
2384TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2385 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002386 send_parameters_.options.audio_network_adaptor = true;
2387 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002388 SetSendParameters(send_parameters_);
2389 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002391 const int initial_num = call_.GetNumCreatedSendStreams();
2392 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002393 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002394 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2395 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002396 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002397 // AudioSendStream not expected to be recreated.
2398 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2399 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002400 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002401}
2402
michaelt6672b262017-01-11 10:17:59 -08002403class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2404 : public WebRtcVoiceEngineTestFake {
2405 public:
2406 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2407 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002408 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2409 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002410 "Enabled/") {}
2411};
2412
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002414// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002416 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002417 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2421 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002423 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002424 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002425 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002426 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002427 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002428 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429
solenberg85a04962015-10-27 03:35:21 -07002430 // Check stats for the added streams.
2431 {
2432 cricket::VoiceMediaInfo info;
2433 EXPECT_EQ(true, channel_->GetStats(&info));
2434
2435 // We have added one send stream. We should see the stats we've set.
2436 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002437 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002438 // We have added one receive stream. We should see empty stats.
2439 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002440 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002441 }
solenberg1ac56142015-10-13 03:58:19 -07002442
solenberg566ef242015-11-06 15:34:49 -08002443 // Start sending - this affects some reported stats.
2444 {
2445 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002446 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002447 EXPECT_EQ(true, channel_->GetStats(&info));
2448 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002449 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002450 }
2451
solenberg2100c0b2017-03-01 11:29:29 -08002452 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002453 {
2454 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002455 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002456 EXPECT_EQ(true, channel_->GetStats(&info));
2457 EXPECT_EQ(1u, info.senders.size());
2458 EXPECT_EQ(0u, info.receivers.size());
2459 }
solenberg1ac56142015-10-13 03:58:19 -07002460
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002461 // Deliver a new packet - a default receive stream should be created and we
2462 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002463 {
2464 cricket::VoiceMediaInfo info;
2465 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2466 SetAudioReceiveStreamStats();
2467 EXPECT_EQ(true, channel_->GetStats(&info));
2468 EXPECT_EQ(1u, info.senders.size());
2469 EXPECT_EQ(1u, info.receivers.size());
2470 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002471 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002472 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473}
2474
2475// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002476// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002478 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2480 EXPECT_TRUE(AddRecvStream(kSsrcY));
2481 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482}
2483
2484// Test that the local SSRC is the same on sending and receiving channels if the
2485// receive channel is created before the send channel.
2486TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002489 EXPECT_TRUE(
2490 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002491 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2492 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002493}
2494
2495// Test that we can properly receive packets.
2496TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002497 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002498 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002500
Yves Gerey665174f2018-06-19 15:03:05 +02002501 EXPECT_TRUE(
2502 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503}
2504
2505// Test that we can properly receive packets on multiple streams.
2506TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002507 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002508 const uint32_t ssrc1 = 1;
2509 const uint32_t ssrc2 = 2;
2510 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002511 EXPECT_TRUE(AddRecvStream(ssrc1));
2512 EXPECT_TRUE(AddRecvStream(ssrc2));
2513 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002514 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002515 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002516 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002517 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002518 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519 }
mflodman3d7db262016-04-29 00:57:13 -07002520
2521 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2522 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2523 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2524
2525 EXPECT_EQ(s1.received_packets(), 0);
2526 EXPECT_EQ(s2.received_packets(), 0);
2527 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002528
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002530 EXPECT_EQ(s1.received_packets(), 0);
2531 EXPECT_EQ(s2.received_packets(), 0);
2532 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002533
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_EQ(s1.received_packets(), 1);
2536 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2537 EXPECT_EQ(s2.received_packets(), 0);
2538 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002539
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002541 EXPECT_EQ(s1.received_packets(), 1);
2542 EXPECT_EQ(s2.received_packets(), 1);
2543 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2544 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002545
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002547 EXPECT_EQ(s1.received_packets(), 1);
2548 EXPECT_EQ(s2.received_packets(), 1);
2549 EXPECT_EQ(s3.received_packets(), 1);
2550 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002551
mflodman3d7db262016-04-29 00:57:13 -07002552 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2553 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2554 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555}
2556
solenberg2100c0b2017-03-01 11:29:29 -08002557// Test that receiving on an unsignaled stream works (a stream is created).
2558TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002559 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002560 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002561
solenberg7e63ef02015-11-20 00:19:43 -08002562 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002563
Mirko Bonadeif859e552018-05-30 15:31:29 +02002564 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002565 EXPECT_TRUE(
2566 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002567}
2568
Seth Hampson5897a6e2018-04-03 11:16:33 -07002569// Tests that when we add a stream without SSRCs, but contains a stream_id
2570// that it is stored and its stream id is later used when the first packet
2571// arrives to properly create a receive stream with a sync label.
2572TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2573 const char kSyncLabel[] = "sync_label";
2574 EXPECT_TRUE(SetupChannel());
2575 cricket::StreamParams unsignaled_stream;
2576 unsignaled_stream.set_stream_ids({kSyncLabel});
2577 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2578 // The stream shouldn't have been created at this point because it doesn't
2579 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002580 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002581
2582 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2583
Mirko Bonadeif859e552018-05-30 15:31:29 +02002584 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002585 EXPECT_TRUE(
2586 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2587 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2588
2589 // Removing the unsignaled stream clears the cached parameters. If a new
2590 // default unsignaled receive stream is created it will not have a sync group.
2591 channel_->RemoveRecvStream(0);
2592 channel_->RemoveRecvStream(kSsrc1);
2593
2594 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2595
Mirko Bonadeif859e552018-05-30 15:31:29 +02002596 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002597 EXPECT_TRUE(
2598 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2599 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2600}
2601
solenberg2100c0b2017-03-01 11:29:29 -08002602// Test that receiving N unsignaled stream works (streams will be created), and
2603// that packets are forwarded to them all.
2604TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002605 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002606 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002607 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2608
solenberg2100c0b2017-03-01 11:29:29 -08002609 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002610 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002611 rtc::SetBE32(&packet[8], ssrc);
2612 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002613
solenberg2100c0b2017-03-01 11:29:29 -08002614 // Verify we have one new stream for each loop iteration.
2615 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002616 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2617 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002618 }
mflodman3d7db262016-04-29 00:57:13 -07002619
solenberg2100c0b2017-03-01 11:29:29 -08002620 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002621 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002622 rtc::SetBE32(&packet[8], ssrc);
2623 DeliverPacket(packet, sizeof(packet));
2624
solenbergebb349d2017-03-13 05:46:15 -07002625 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002626 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2627 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2628 }
2629
2630 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2631 constexpr uint32_t kAnotherSsrc = 667;
2632 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002633 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002634
2635 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002636 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002637 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002638 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002639 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2640 EXPECT_EQ(2, streams[i]->received_packets());
2641 }
2642 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2643 EXPECT_EQ(1, streams[i]->received_packets());
2644 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002645 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002646}
2647
solenberg2100c0b2017-03-01 11:29:29 -08002648// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002649// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002650TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002652 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002653 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2654
2655 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002656 const uint32_t signaled_ssrc = 1;
2657 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002658 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002659 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002660 EXPECT_TRUE(
2661 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002662 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002663
2664 // Note that the first unknown SSRC cannot be 0, because we only support
2665 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002666 const uint32_t unsignaled_ssrc = 7011;
2667 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002668 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002669 EXPECT_TRUE(
2670 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002671 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002672
2673 DeliverPacket(packet, sizeof(packet));
2674 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2675
2676 rtc::SetBE32(&packet[8], signaled_ssrc);
2677 DeliverPacket(packet, sizeof(packet));
2678 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002679 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002680}
2681
solenberg4904fb62017-02-17 12:01:14 -08002682// Two tests to verify that adding a receive stream with the same SSRC as a
2683// previously added unsignaled stream will only recreate underlying stream
2684// objects if the stream parameters have changed.
2685TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2686 EXPECT_TRUE(SetupChannel());
2687
2688 // Spawn unsignaled stream with SSRC=1.
2689 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002690 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002691 EXPECT_TRUE(
2692 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002693
2694 // Verify that the underlying stream object in Call is not recreated when a
2695 // stream with SSRC=1 is added.
2696 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002697 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002698 int audio_receive_stream_id = streams.front()->id();
2699 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002700 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002701 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2702}
2703
2704TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2705 EXPECT_TRUE(SetupChannel());
2706
2707 // Spawn unsignaled stream with SSRC=1.
2708 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002709 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002710 EXPECT_TRUE(
2711 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002712
2713 // Verify that the underlying stream object in Call *is* recreated when a
2714 // stream with SSRC=1 is added, and which has changed stream parameters.
2715 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002716 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002717 int audio_receive_stream_id = streams.front()->id();
2718 cricket::StreamParams stream_params;
2719 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002720 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002721 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002723 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2724}
2725
solenberg1ac56142015-10-13 03:58:19 -07002726// Test that AddRecvStream creates new stream.
2727TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002728 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002729 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730}
2731
2732// Test that after adding a recv stream, we do not decode more codecs than
2733// those previously passed into SetRecvCodecs.
2734TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002735 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002736 cricket::AudioRecvParameters parameters;
2737 parameters.codecs.push_back(kIsacCodec);
2738 parameters.codecs.push_back(kPcmuCodec);
2739 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002740 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002741 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2742 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2743 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744}
2745
2746// Test that we properly clean up any streams that were added, even if
2747// not explicitly removed.
2748TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002749 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002750 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002751 EXPECT_TRUE(AddRecvStream(1));
2752 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002753
Mirko Bonadeif859e552018-05-30 15:31:29 +02002754 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2755 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002756 delete channel_;
2757 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002758 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2759 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760}
2761
wu@webrtc.org78187522013-10-07 23:32:02 +00002762TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002763 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002764 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002765}
2766
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002767TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002768 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002769 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002770 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002771}
2772
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002773// Test the InsertDtmf on default send stream as caller.
2774TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002775 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776}
2777
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002778// Test the InsertDtmf on default send stream as callee
2779TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002780 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002781}
2782
2783// Test the InsertDtmf on specified send stream as caller.
2784TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002785 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002786}
2787
2788// Test the InsertDtmf on specified send stream as callee.
2789TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002790 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
Johannes Kron9190b822018-10-29 11:22:05 +01002793// Test propagation of extmap allow mixed setting.
2794TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2795 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2796}
2797TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2798 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2799}
2800TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2801 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2802}
2803TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2804 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2805}
2806
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002808 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002809 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002810 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2811 .Times(9)
2812 .WillRepeatedly(Return(false));
2813 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2814 .Times(4)
2815 .WillRepeatedly(Return(false));
2816 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2817 .Times(2)
2818 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002819
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002820 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002821 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822
solenberg246b8172015-12-08 09:50:23 -08002823 // Nothing set in AudioOptions, so everything should be as default.
2824 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002825 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002826 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002827 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002828 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002829 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002830 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831
Sam Zackrissonba502232019-01-04 10:36:48 +01002832 // Turn typing detection off.
2833 send_parameters_.options.typing_detection = false;
2834 SetSendParameters(send_parameters_);
2835 EXPECT_FALSE(IsTypingDetectionEnabled());
2836
2837 // Leave typing detection unchanged, but non-default.
2838 send_parameters_.options.typing_detection = absl::nullopt;
2839 SetSendParameters(send_parameters_);
2840 EXPECT_FALSE(IsTypingDetectionEnabled());
2841
2842 // Turn typing detection on.
2843 send_parameters_.options.typing_detection = true;
2844 SetSendParameters(send_parameters_);
2845 EXPECT_TRUE(IsTypingDetectionEnabled());
2846
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002847 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002848 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002849 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002850 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002851
2852 // Turn echo cancellation back on, with settings, and make sure
2853 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002854 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002855 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002856 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002857
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002858 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2859 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002860 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002861 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002862 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002863
2864 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 send_parameters_.options.delay_agnostic_aec = false;
2866 send_parameters_.options.extended_filter_aec = false;
2867 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002868 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002869 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002870
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002871 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002873 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002874 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002875
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002876 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002877 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002878 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002879 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002880 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
2882 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002883 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002884 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002885 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002886 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002887
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002888 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002889 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002891 send_parameters_.options.noise_suppression = false;
2892 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002894 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002895 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002896 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002897 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
solenberg1ac56142015-10-13 03:58:19 -07002899 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002900 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002903 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002904 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905}
2906
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002908 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002909 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2910 .Times(8)
2911 .WillRepeatedly(Return(false));
2912 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2913 .Times(8)
2914 .WillRepeatedly(Return(false));
2915 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2916 .Times(8)
2917 .WillRepeatedly(Return(false));
2918 EXPECT_CALL(adm_, RecordingIsInitialized())
2919 .Times(2)
2920 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002921 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2922 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002923 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002924
kwiberg686a8ef2016-02-26 03:00:35 -08002925 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002926 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2927 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2928 cricket::AudioOptions(),
2929 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002930 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002931 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2932 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2933 cricket::AudioOptions(),
2934 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935
2936 // Have to add a stream to make SetSend work.
2937 cricket::StreamParams stream1;
2938 stream1.ssrcs.push_back(1);
2939 channel1->AddSendStream(stream1);
2940 cricket::StreamParams stream2;
2941 stream2.ssrcs.push_back(2);
2942 channel2->AddSendStream(stream2);
2943
2944 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002946 parameters_options_all.options.echo_cancellation = true;
2947 parameters_options_all.options.auto_gain_control = true;
2948 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002949 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002950 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002951 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002952 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002953 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002954 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002955 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002956 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002957 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002958 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959
2960 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002961 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002962 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002963 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002964 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002965 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002966 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002967 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002968 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002969 expected_options.echo_cancellation = true;
2970 expected_options.auto_gain_control = true;
2971 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002972 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002973
2974 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002975 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002976 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002977 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002978 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002979 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002980 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002981 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002982 expected_options.echo_cancellation = true;
2983 expected_options.auto_gain_control = false;
2984 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002985 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002987 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002988 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002989 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002990 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002991 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002993 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002994 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002995 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002996 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002997 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002999 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003000 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003001 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003002 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003003 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3007 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003008 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3009 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003010 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003011 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003012 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003013 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003014 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003015 expected_options.echo_cancellation = true;
3016 expected_options.auto_gain_control = false;
3017 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003018 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019}
3020
wu@webrtc.orgde305012013-10-31 15:40:38 +00003021// This test verifies DSCP settings are properly applied on voice media channel.
3022TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003023 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003024 cricket::FakeNetworkInterface network_interface;
3025 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003026 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003027 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003028
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003029 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003030
Sebastian Jansson84848f22018-11-16 10:40:36 +01003031 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3032 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3033 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003034 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003035 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3036 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3037
3038 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003039 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3040 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3041 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003042 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003043 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3044
3045 // Create a send stream to configure
3046 EXPECT_TRUE(
3047 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3048 parameters = channel->GetRtpSendParameters(kSsrcZ);
3049 ASSERT_FALSE(parameters.encodings.empty());
3050
3051 // Various priorities map to various dscp values.
3052 parameters.encodings[0].network_priority = 4.0;
3053 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003054 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003055 parameters.encodings[0].network_priority = 0.5;
3056 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3057 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3058
3059 // A bad priority does not change the dscp value.
3060 parameters.encodings[0].network_priority = 0.0;
3061 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3062 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003063
Tim Haloun6ca98362018-09-17 17:06:08 -07003064 // Packets should also self-identify their dscp in PacketOptions.
3065 const uint8_t kData[10] = {0};
3066 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003067 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003068
nisse51542be2016-02-12 02:27:06 -08003069 // Verify that setting the option to false resets the
3070 // DiffServCodePoint.
3071 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003072 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3073 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3074 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003075 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003076 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3077 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3078
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003079 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003080}
3081
solenberg4bac9c52015-10-09 02:32:53 -07003082TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003083 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003084 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003085 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003086 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003087 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003088 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3089 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3090 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003091}
3092
solenberg2100c0b2017-03-01 11:29:29 -08003093TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003095
3096 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003097 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003098 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3099
3100 // Should remember the volume "2" which will be set on new unsignaled streams,
3101 // and also set the gain to 2 on existing unsignaled streams.
3102 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3103 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3104
3105 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3106 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3107 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3108 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3109 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3110 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3111
3112 // Setting gain with SSRC=0 should affect all unsignaled streams.
3113 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003114 if (kMaxUnsignaledRecvStreams > 1) {
3115 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3116 }
solenberg2100c0b2017-03-01 11:29:29 -08003117 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3118
3119 // Setting gain on an individual stream affects only that.
3120 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003121 if (kMaxUnsignaledRecvStreams > 1) {
3122 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3123 }
solenberg2100c0b2017-03-01 11:29:29 -08003124 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003125}
3126
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003127TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3128 EXPECT_TRUE(SetupChannel());
3129 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3130 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3131
3132 cricket::StreamParams stream;
3133 stream.ssrcs.push_back(kSsrcY);
3134 EXPECT_TRUE(channel_->AddRecvStream(stream));
3135 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3136 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3137 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3138}
3139
3140TEST_F(WebRtcVoiceEngineTestFake,
3141 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3142 // Here base minimum delay is abbreviated to delay in comments for shortness.
3143 EXPECT_TRUE(SetupChannel());
3144
3145 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3146 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3147 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3148 // Check that it doesn't provide default values for unknown ssrc.
3149 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3150
3151 // Check that default value for unsignaled streams is 0.
3152 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3153
3154 // Should remember the delay 100 which will be set on new unsignaled streams,
3155 // and also set the delay to 100 on existing unsignaled streams.
3156 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3157 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3158 // Check that it doesn't provide default values for unknown ssrc.
3159 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3160
3161 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3162 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3163 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3164 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3165 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3166 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3167
3168 // Setting delay with SSRC=0 should affect all unsignaled streams.
3169 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3170 if (kMaxUnsignaledRecvStreams > 1) {
3171 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3172 }
3173 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3174
3175 // Setting delay on an individual stream affects only that.
3176 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3177 if (kMaxUnsignaledRecvStreams > 1) {
3178 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3179 }
3180 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3181 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3182 // Check that it doesn't provide default values for unknown ssrc.
3183 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3184}
3185
Seth Hampson845e8782018-03-02 11:34:10 -08003186TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003187 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003188 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003189
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003191 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003192 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003193 // Creating two channels to make sure that sync label is set properly for both
3194 // the default voice channel and following ones.
3195 EXPECT_TRUE(channel_->AddRecvStream(sp));
3196 sp.ssrcs[0] += 1;
3197 EXPECT_TRUE(channel_->AddRecvStream(sp));
3198
Mirko Bonadeif859e552018-05-30 15:31:29 +02003199 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003200 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003201 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003202 << "SyncGroup should be set based on stream id";
3203 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003204 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003205 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003206}
3207
solenberg3a941542015-11-16 07:34:50 -08003208// TODO(solenberg): Remove, once recv streams are configured through Call.
3209// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003210TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003211 // Test that setting the header extensions results in the expected state
3212 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003213 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214 ssrcs.push_back(223);
3215 ssrcs.push_back(224);
3216
solenbergff976312016-03-30 23:28:51 -07003217 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003218 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003219 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003220 EXPECT_TRUE(
3221 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 }
3223
Mirko Bonadeif859e552018-05-30 15:31:29 +02003224 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003225 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003226 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003227 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003228 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229 }
3230
3231 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003232 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003233 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003234 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003235 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003236 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003237 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003238 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003239 EXPECT_NE(nullptr, s);
3240 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003241 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3242 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003243 for (const auto& s_ext : s_exts) {
3244 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003245 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003246 }
3247 }
3248 }
3249 }
3250
3251 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003252 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003253 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003254 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003256 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003257 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258}
3259
3260TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3261 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003262 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003263 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003264 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003265 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3266 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003268 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269
solenbergff976312016-03-30 23:28:51 -07003270 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 cricket::WebRtcVoiceMediaChannel* media_channel =
3272 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003273 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003274 EXPECT_TRUE(media_channel->AddRecvStream(
3275 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3276
Mirko Bonadeif859e552018-05-30 15:31:29 +02003277 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003278 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003279 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003280 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003281 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003282 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003283 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003284 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003285}
Minyue2013aec2015-05-13 14:14:42 +02003286
solenberg0a617e22015-10-20 15:49:38 -07003287// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003288// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003289TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003290 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_TRUE(AddRecvStream(kSsrcY));
3292 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003293 EXPECT_TRUE(
3294 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003295 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3296 EXPECT_TRUE(AddRecvStream(kSsrcW));
3297 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003298}
3299
solenberg7602aab2016-11-14 11:30:07 -08003300TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3301 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003302 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003303 EXPECT_TRUE(
3304 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003305 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3306 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3307 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003308 EXPECT_TRUE(
3309 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003310 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3311 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003312}
stefan658910c2015-09-03 05:48:32 -07003313
deadbeef884f5852016-01-15 09:20:04 -08003314TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003315 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003316 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3317 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003318
3319 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003320 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3321 EXPECT_TRUE(AddRecvStream(kSsrcX));
3322 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003323
3324 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003325 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3326 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003327
3328 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003329 channel_->SetRawAudioSink(kSsrcX, nullptr);
3330 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003331}
3332
solenberg2100c0b2017-03-01 11:29:29 -08003333TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003334 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003335 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3336 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003337 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3338 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003339
3340 // Should be able to set a default sink even when no stream exists.
3341 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3342
solenberg2100c0b2017-03-01 11:29:29 -08003343 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3344 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003345 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003347
3348 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003349 channel_->SetRawAudioSink(kSsrc0, nullptr);
3350 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003351
3352 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003353 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3354 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003355
3356 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003357 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003358 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003359 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3360
3361 // Spawn another unsignaled stream - it should be assigned the default sink
3362 // and the previous unsignaled stream should lose it.
3363 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3364 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3365 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3366 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003367 if (kMaxUnsignaledRecvStreams > 1) {
3368 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3369 }
solenberg2100c0b2017-03-01 11:29:29 -08003370 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3371
3372 // Reset the default sink - the second unsignaled stream should lose it.
3373 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003374 if (kMaxUnsignaledRecvStreams > 1) {
3375 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3376 }
solenberg2100c0b2017-03-01 11:29:29 -08003377 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3378
3379 // Try setting the default sink while two streams exists.
3380 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003381 if (kMaxUnsignaledRecvStreams > 1) {
3382 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3383 }
solenberg2100c0b2017-03-01 11:29:29 -08003384 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3385
3386 // Try setting the sink for the first unsignaled stream using its known SSRC.
3387 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003388 if (kMaxUnsignaledRecvStreams > 1) {
3389 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3390 }
solenberg2100c0b2017-03-01 11:29:29 -08003391 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003392 if (kMaxUnsignaledRecvStreams > 1) {
3393 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3394 }
deadbeef884f5852016-01-15 09:20:04 -08003395}
3396
skvlad7a43d252016-03-22 15:32:27 -07003397// Test that, just like the video channel, the voice channel communicates the
3398// network state to the call.
3399TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003400 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003401
3402 EXPECT_EQ(webrtc::kNetworkUp,
3403 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3404 EXPECT_EQ(webrtc::kNetworkUp,
3405 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3406
3407 channel_->OnReadyToSend(false);
3408 EXPECT_EQ(webrtc::kNetworkDown,
3409 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3410 EXPECT_EQ(webrtc::kNetworkUp,
3411 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3412
3413 channel_->OnReadyToSend(true);
3414 EXPECT_EQ(webrtc::kNetworkUp,
3415 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3416 EXPECT_EQ(webrtc::kNetworkUp,
3417 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3418}
3419
aleloi18e0b672016-10-04 02:45:47 -07003420// Test that playout is still started after changing parameters
3421TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3422 SetupRecvStream();
3423 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003424 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003425
3426 // Changing RTP header extensions will recreate the AudioReceiveStream.
3427 cricket::AudioRecvParameters parameters;
3428 parameters.extensions.push_back(
3429 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3430 channel_->SetRecvParameters(parameters);
3431
solenberg2100c0b2017-03-01 11:29:29 -08003432 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003433}
3434
Zhi Huangfa266ef2017-12-13 10:27:46 -08003435// Tests when GetSources is called with non-existing ssrc, it will return an
3436// empty list of RtpSource without crashing.
3437TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3438 // Setup an recv stream with |kSsrcX|.
3439 SetupRecvStream();
3440 cricket::WebRtcVoiceMediaChannel* media_channel =
3441 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3442 // Call GetSources with |kSsrcY| which doesn't exist.
3443 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3444 EXPECT_EQ(0u, sources.size());
3445}
3446
stefan658910c2015-09-03 05:48:32 -07003447// Tests that the library initializes and shuts down properly.
3448TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003449 // If the VoiceEngine wants to gather available codecs early, that's fine but
3450 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003451 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3452 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003453 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003454 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003455 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003456 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003457 task_queue_factory.get(), &adm,
3458 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003459 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003460 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003461 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003462 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003463 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003464 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3465 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3466 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003467 EXPECT_TRUE(channel != nullptr);
3468 delete channel;
solenbergff976312016-03-30 23:28:51 -07003469}
stefan658910c2015-09-03 05:48:32 -07003470
solenbergff976312016-03-30 23:28:51 -07003471// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003472TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003473 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3474 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003475 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003476 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003477 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003478 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003479 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003480 {
peaha9cc40b2017-06-29 08:32:09 -07003481 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003482 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003483 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003484 task_queue_factory.get(), &adm,
3485 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003486 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003487 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003488 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003489 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003490 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003491 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3492 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3493 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003494 EXPECT_TRUE(channel != nullptr);
3495 delete channel;
3496 }
stefan658910c2015-09-03 05:48:32 -07003497}
3498
ossu20a4b3f2017-04-27 02:08:52 -07003499// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3500TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003501 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3502 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003503 // TODO(ossu): Why are the payload types of codecs with non-static payload
3504 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003505 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003506 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003507 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003508 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003509 task_queue_factory.get(), &adm,
3510 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003511 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003512 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003513 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003514 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003515 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003516 (clockrate == 0 || codec.clockrate == clockrate);
3517 };
3518 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003519 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003520 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003521 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003522 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003523 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003524 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003525 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003526 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003527 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003528 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003529 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003530 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3531 // Remove these checks once both send and receive side assigns payload
3532 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003533 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003534 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003535 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003536 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003537 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003538 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003539 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003540 EXPECT_EQ(111, codec.id);
3541 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3542 EXPECT_EQ("10", codec.params.find("minptime")->second);
3543 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3544 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003545 }
3546 }
stefan658910c2015-09-03 05:48:32 -07003547}
3548
3549// Tests that VoE supports at least 32 channels
3550TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003551 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3552 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003553 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003554 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003555 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003556 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003557 task_queue_factory.get(), &adm,
3558 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003559 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003560 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003561 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003562 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003563 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003564
3565 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003566 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003567 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003568 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3569 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3570 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003571 if (!channel)
3572 break;
stefan658910c2015-09-03 05:48:32 -07003573 channels[num_channels++] = channel;
3574 }
3575
Mirko Bonadeif859e552018-05-30 15:31:29 +02003576 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003577 EXPECT_EQ(expected, num_channels);
3578
3579 while (num_channels > 0) {
3580 delete channels[--num_channels];
3581 }
stefan658910c2015-09-03 05:48:32 -07003582}
3583
3584// Test that we set our preferred codecs properly.
3585TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003586 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3587 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003588 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3589 // - Check that our builtin codecs are usable by Channel.
3590 // - The codecs provided by the engine is usable by Channel.
3591 // It does not check that the codecs in the RecvParameters are actually
3592 // what we sent in - though it's probably reasonable to expect so, if
3593 // SetRecvParameters returns true.
3594 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003595 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003596 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003597 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003598 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003599 task_queue_factory.get(), &adm,
3600 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003601 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003602 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003603 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003604 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003605 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003606 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003607 cricket::AudioOptions(),
3608 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003609 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003610 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003611 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003612}
ossu9def8002017-02-09 05:14:32 -08003613
3614TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3615 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003616 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3617 {48000, 2, 16000, 10000, 20000}};
3618 spec1.info.allow_comfort_noise = false;
3619 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003620 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003621 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3622 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003623 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003624 specs.push_back(webrtc::AudioCodecSpec{
3625 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3626 {16000, 1, 13300}});
3627 specs.push_back(
3628 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3629 specs.push_back(
3630 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003631
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003632 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3633 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003634 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3635 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3636 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003637 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003638 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003639 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003640 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003641
peaha9cc40b2017-06-29 08:32:09 -07003642 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003643 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003644 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3645 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003646 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003647 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003648 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003649 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003650
3651 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3652 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003653 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3654 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3655 if (codecs.size() > index)
3656 return codecs[index];
3657 return missing_codec;
3658 };
ossu9def8002017-02-09 05:14:32 -08003659
3660 // Ensure the general codecs are generated first and in order.
3661 for (size_t i = 0; i != specs.size(); ++i) {
3662 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3663 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3664 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3665 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3666 }
3667
3668 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003669 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003670 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3671 for (size_t i = 0; i != codecs.size(); ++i) {
3672 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003673 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003674 codec.clockrate == format.clockrate_hz &&
3675 codec.channels == format.num_channels) {
3676 return rtc::checked_cast<int>(i);
3677 }
3678 }
3679 return -1;
3680 };
ossu9def8002017-02-09 05:14:32 -08003681
3682 // Ensure all supplementary codecs are generated last. Their internal ordering
3683 // is not important.
3684 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3685 const int num_specs = static_cast<int>(specs.size());
3686 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3687 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3688 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3689 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3690 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3691 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3692 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3693}