blob: 969c10ce97889d53229a68ca86078490c9d20155 [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(
101 *adm, SetPlayoutDevice(
102 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
103 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
104 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700105#else
106 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
107#endif // #if defined(WEBRTC_WIN)
108 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
109 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
110 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100111#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200112 EXPECT_CALL(
113 *adm, SetRecordingDevice(
114 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
115 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
116 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100117#else
118 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
119#endif // #if defined(WEBRTC_WIN)
120 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
121 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
122 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700123 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
124 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
125 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100126
127 // Teardown.
128 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
129 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
130 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
131 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200132 EXPECT_CALL(*adm, Release())
133 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100134 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700135}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200136} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137
solenbergff976312016-03-30 23:28:51 -0700138// Tests that our stub library "works".
139TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100140 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
141 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700142 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700143 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700144 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
145 new rtc::RefCountedObject<
146 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700147 webrtc::AudioProcessing::Config apm_config;
148 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
149 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700150 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700151 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700152 {
ossuc54071d2016-08-17 02:45:41 -0700153 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100154 task_queue_factory.get(), &adm,
155 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100156 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700157 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700158 }
solenbergff976312016-03-30 23:28:51 -0700159}
160
deadbeef884f5852016-01-15 09:20:04 -0800161class FakeAudioSink : public webrtc::AudioSinkInterface {
162 public:
163 void OnData(const Data& audio) override {}
164};
165
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800166class FakeAudioSource : public cricket::AudioSource {
167 void SetSink(Sink* sink) override {}
168};
169
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000170class WebRtcVoiceEngineTestFake : public testing::Test {
171 public:
stefanba4c0e42016-02-04 04:12:24 -0800172 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
173
174 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100175 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
176 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700177 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700178 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100179 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700180 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800181 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700182 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800183 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700184 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
185 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700186 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700187 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800188 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100189 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800190 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700191 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800192 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700193 // factories. Those tests should probably be moved elsewhere.
194 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
195 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100196 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100197 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
198 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700199 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200200 send_parameters_.codecs.push_back(kPcmuCodec);
201 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100202
solenberg76377c52017-02-21 00:54:31 -0800203 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200204 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800205 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100206 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100207 VerifyGainControlEnabledCorrectly();
208 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 }
solenberg8189b022016-06-14 12:13:00 -0700210
solenbergff976312016-03-30 23:28:51 -0700211 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700212 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100213 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
214 cricket::AudioOptions(),
215 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupRecvStream() {
220 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700221 return false;
222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200227 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
228 }
229
230 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700231 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000232 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
Florent Castellidacec712018-05-24 16:24:21 +0200234 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800235 return false;
236 }
peaha9cc40b2017-06-29 08:32:09 -0700237 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800238 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 }
solenberg8189b022016-06-14 12:13:00 -0700240
241 bool AddRecvStream(uint32_t ssrc) {
242 EXPECT_TRUE(channel_);
243 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
244 }
245
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700247 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700248 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800249 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
250 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700251 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800252 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000253 }
solenberg8189b022016-06-14 12:13:00 -0700254
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700256 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700257 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 }
solenberg8189b022016-06-14 12:13:00 -0700259
Yves Gerey665174f2018-06-19 15:03:05 +0200260 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100262 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
263 const auto* send_stream = call_.GetAudioSendStream(ssrc);
264 EXPECT_TRUE(send_stream);
265 return *send_stream;
266 }
267
deadbeef884f5852016-01-15 09:20:04 -0800268 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
269 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
270 EXPECT_TRUE(recv_stream);
271 return *recv_stream;
272 }
273
solenberg3a941542015-11-16 07:34:50 -0800274 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800275 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800276 }
277
solenberg7add0582015-11-20 09:59:34 -0800278 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800279 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800280 }
281
solenberg059fb442016-10-26 05:12:24 -0700282 void SetSend(bool enable) {
283 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700284 if (enable) {
285 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700289 }
solenberg059fb442016-10-26 05:12:24 -0700290 channel_->SetSend(enable);
291 }
292
293 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700294 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700295 ASSERT_TRUE(channel_);
296 EXPECT_TRUE(channel_->SetSendParameters(params));
297 }
298
Yves Gerey665174f2018-06-19 15:03:05 +0200299 void SetAudioSend(uint32_t ssrc,
300 bool enable,
301 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700302 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700303 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700304 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700305 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700306 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700307 }
308 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700309 }
310
Yves Gerey665174f2018-06-19 15:03:05 +0200311 void TestInsertDtmf(uint32_t ssrc,
312 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800313 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700314 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700316 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200318 EXPECT_TRUE(
319 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
324 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800327 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330
331 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700332 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200334 EXPECT_TRUE(
335 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000336 }
337
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 // Test send.
342 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800343 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800345 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800346 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800347 EXPECT_EQ(codec.id, telephone_event.payload_type);
348 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(2, telephone_event.event_code);
350 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 }
352
Johannes Kron9190b822018-10-29 11:22:05 +0100353 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
354 // For a caller, the answer will be applied in set remote description
355 // where SetSendParameters() is called.
356 EXPECT_TRUE(SetupChannel());
357 EXPECT_TRUE(
358 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
359 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
360 SetSendParameters(send_parameters_);
361 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
362 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
363 }
364
365 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
366 // For a callee, the answer will be applied in set local description
367 // where SetExtmapAllowMixed() and AddSendStream() are called.
368 EXPECT_TRUE(SetupChannel());
369 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
370 EXPECT_TRUE(
371 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
372
373 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
374 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
375 }
376
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 // Test that send bandwidth is set correctly.
378 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000379 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
380 // |expected_result| is the expected result from SetMaxSendBandwidth().
381 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700382 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
383 int max_bitrate,
384 bool expected_result,
385 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200386 cricket::AudioSendParameters parameters;
387 parameters.codecs.push_back(codec);
388 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700389 if (expected_result) {
390 SetSendParameters(parameters);
391 } else {
392 EXPECT_FALSE(channel_->SetSendParameters(parameters));
393 }
solenberg2100c0b2017-03-01 11:29:29 -0800394 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 }
396
skvlade0d46372016-04-07 22:59:22 -0700397 // Sets the per-stream maximum bitrate limit for the specified SSRC.
398 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700399 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700400 EXPECT_EQ(1UL, parameters.encodings.size());
401
Oskar Sundbom78807582017-11-16 11:09:55 +0100402 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800403 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700404 }
405
solenberg059fb442016-10-26 05:12:24 -0700406 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700407 cricket::AudioSendParameters send_parameters;
408 send_parameters.codecs.push_back(codec);
409 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700410 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700411 }
412
ossu20a4b3f2017-04-27 02:08:52 -0700413 void CheckSendCodecBitrate(int32_t ssrc,
414 const char expected_name[],
415 int expected_bitrate) {
416 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
417 EXPECT_EQ(expected_name, spec->format.name);
418 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700419 }
420
Danil Chapovalov00c71832018-06-15 15:58:38 +0200421 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700422 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700423 }
424
Danil Chapovalov00c71832018-06-15 15:58:38 +0200425 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
426 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700427 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
428 }
429
skvlade0d46372016-04-07 22:59:22 -0700430 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
431 int global_max,
432 int stream_max,
433 bool expected_result,
434 int expected_codec_bitrate) {
435 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800436 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700437
438 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700439 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800440 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700441
442 // Verify that reading back the parameters gives results
443 // consistent with the Set() result.
444 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800445 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700446 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
447 EXPECT_EQ(expected_result ? stream_max : -1,
448 resulting_parameters.encodings[0].max_bitrate_bps);
449
450 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700452 }
453
stefan13f1a0a2016-11-30 07:22:58 -0800454 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
455 int expected_min_bitrate_bps,
456 const char* start_bitrate_kbps,
457 int expected_start_bitrate_bps,
458 const char* max_bitrate_kbps,
459 int expected_max_bitrate_bps) {
460 EXPECT_TRUE(SetupSendStream());
461 auto& codecs = send_parameters_.codecs;
462 codecs.clear();
463 codecs.push_back(kOpusCodec);
464 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
465 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
466 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100467 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
468 SetSdpBitrateParameters(
469 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
470 expected_min_bitrate_bps),
471 Field(&BitrateConstraints::start_bitrate_bps,
472 expected_start_bitrate_bps),
473 Field(&BitrateConstraints::max_bitrate_bps,
474 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800475
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100476 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800477 }
478
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000479 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700480 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000481
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000484
485 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700486 send_parameters_.extensions.push_back(
487 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700488 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800489 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200492 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000495
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000496 // Ensure extension is set properly.
497 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700498 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700499 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800500 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
501 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
502 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000503
solenberg7add0582015-11-20 09:59:34 -0800504 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200505 EXPECT_TRUE(
506 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800507 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
508 call_.GetAudioSendStream(kSsrcY));
509 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
510 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
513 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200514 send_parameters_.codecs.push_back(kPcmuCodec);
515 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700516 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800517 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
518 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000519 }
520
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700522 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000523
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526
527 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700528 recv_parameters_.extensions.push_back(
529 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800530 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800531 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000532
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000533 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800534 recv_parameters_.extensions.clear();
535 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800536 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000537
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000538 // Ensure extension is set properly.
539 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700540 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800541 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800542 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
543 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
544 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000545
solenberg7add0582015-11-20 09:59:34 -0800546 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800547 EXPECT_TRUE(AddRecvStream(kSsrcY));
548 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
549 call_.GetAudioReceiveStream(kSsrcY));
550 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
551 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
552 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000553
554 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800555 recv_parameters_.extensions.clear();
556 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800557 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
558 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000559 }
560
solenberg85a04962015-10-27 03:35:21 -0700561 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
562 webrtc::AudioSendStream::Stats stats;
563 stats.local_ssrc = 12;
564 stats.bytes_sent = 345;
565 stats.packets_sent = 678;
566 stats.packets_lost = 9012;
567 stats.fraction_lost = 34.56f;
568 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100569 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700570 stats.ext_seqnum = 789;
571 stats.jitter_ms = 12;
572 stats.rtt_ms = 345;
573 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100574 stats.apm_statistics.delay_median_ms = 234;
575 stats.apm_statistics.delay_standard_deviation_ms = 567;
576 stats.apm_statistics.echo_return_loss = 890;
577 stats.apm_statistics.echo_return_loss_enhancement = 1234;
578 stats.apm_statistics.residual_echo_likelihood = 0.432f;
579 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100580 stats.ana_statistics.bitrate_action_counter = 321;
581 stats.ana_statistics.channel_action_counter = 432;
582 stats.ana_statistics.dtx_action_counter = 543;
583 stats.ana_statistics.fec_action_counter = 654;
584 stats.ana_statistics.frame_length_increase_counter = 765;
585 stats.ana_statistics.frame_length_decrease_counter = 876;
586 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700587 stats.typing_noise_detected = true;
588 return stats;
589 }
590 void SetAudioSendStreamStats() {
591 for (auto* s : call_.GetAudioSendStreams()) {
592 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200593 }
solenberg85a04962015-10-27 03:35:21 -0700594 }
solenberg566ef242015-11-06 15:34:49 -0800595 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
596 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700597 const auto stats = GetAudioSendStreamStats();
598 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
599 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
600 EXPECT_EQ(info.packets_sent, stats.packets_sent);
601 EXPECT_EQ(info.packets_lost, stats.packets_lost);
602 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
603 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800604 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700605 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
606 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
607 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
608 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100609 EXPECT_EQ(info.apm_statistics.delay_median_ms,
610 stats.apm_statistics.delay_median_ms);
611 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
612 stats.apm_statistics.delay_standard_deviation_ms);
613 EXPECT_EQ(info.apm_statistics.echo_return_loss,
614 stats.apm_statistics.echo_return_loss);
615 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
616 stats.apm_statistics.echo_return_loss_enhancement);
617 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
618 stats.apm_statistics.residual_echo_likelihood);
619 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
620 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700621 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
622 stats.ana_statistics.bitrate_action_counter);
623 EXPECT_EQ(info.ana_statistics.channel_action_counter,
624 stats.ana_statistics.channel_action_counter);
625 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
626 stats.ana_statistics.dtx_action_counter);
627 EXPECT_EQ(info.ana_statistics.fec_action_counter,
628 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700629 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
630 stats.ana_statistics.frame_length_increase_counter);
631 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
632 stats.ana_statistics.frame_length_decrease_counter);
633 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
634 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800635 EXPECT_EQ(info.typing_noise_detected,
636 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700637 }
638
639 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
640 webrtc::AudioReceiveStream::Stats stats;
641 stats.remote_ssrc = 123;
642 stats.bytes_rcvd = 456;
643 stats.packets_rcvd = 768;
644 stats.packets_lost = 101;
645 stats.fraction_lost = 23.45f;
646 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100647 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700648 stats.ext_seqnum = 678;
649 stats.jitter_ms = 901;
650 stats.jitter_buffer_ms = 234;
651 stats.jitter_buffer_preferred_ms = 567;
652 stats.delay_estimate_ms = 890;
653 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700654 stats.total_samples_received = 5678901;
655 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200656 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200657 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100658 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700659 stats.expand_rate = 5.67f;
660 stats.speech_expand_rate = 8.90f;
661 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200662 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.accelerate_rate = 4.56f;
664 stats.preemptive_expand_rate = 7.89f;
665 stats.decoding_calls_to_silence_generator = 12;
666 stats.decoding_calls_to_neteq = 345;
667 stats.decoding_normal = 67890;
668 stats.decoding_plc = 1234;
669 stats.decoding_cng = 5678;
670 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700671 stats.decoding_muted_output = 3456;
672 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200673 return stats;
674 }
675 void SetAudioReceiveStreamStats() {
676 for (auto* s : call_.GetAudioReceiveStreams()) {
677 s->SetStats(GetAudioReceiveStreamStats());
678 }
679 }
680 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700681 const auto stats = GetAudioReceiveStreamStats();
682 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
683 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200684 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
685 stats.packets_rcvd);
686 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
687 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700688 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
689 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800690 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
692 stats.ext_seqnum);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
695 stats.jitter_buffer_ms);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700697 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
699 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700700 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700701 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
702 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200703 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200704 EXPECT_EQ(info.jitter_buffer_delay_seconds,
705 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100706 EXPECT_EQ(info.jitter_buffer_emitted_count,
707 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700708 EXPECT_EQ(info.expand_rate, stats.expand_rate);
709 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
710 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200711 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700712 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
713 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200714 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700715 stats.decoding_calls_to_silence_generator);
716 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
717 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
718 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
719 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
720 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700721 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700722 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200723 }
hbos1acfbd22016-11-17 23:43:29 -0800724 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
725 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
726 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
727 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
728 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
729 codec.ToCodecParameters());
730 }
731 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
732 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
733 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
734 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
735 codec.ToCodecParameters());
736 }
737 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200738
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100739 void VerifyGainControlEnabledCorrectly() {
740 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
741 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
742 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
743 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
744 }
745
746 void VerifyGainControlDefaultSettings() {
747 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
748 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
749 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
750 }
751
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200752 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100753 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200754 }
755
peah8271d042016-11-22 07:24:52 -0800756 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100757 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800758 }
759
Sam Zackrissonba502232019-01-04 10:36:48 +0100760 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100761 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100762 }
763
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000764 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100765 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700766 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700767 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800768 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200769 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700770 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700771 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200772 cricket::AudioSendParameters send_parameters_;
773 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800774 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700775 webrtc::AudioProcessing::Config apm_config_;
776
stefanba4c0e42016-02-04 04:12:24 -0800777 private:
778 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779};
780
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100782TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700783 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784}
785
solenberg31fec402016-05-06 02:13:12 -0700786// Test that we can add a send stream and that it has the correct defaults.
787TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
788 EXPECT_TRUE(SetupChannel());
789 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800790 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
791 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
792 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700793 EXPECT_EQ("", config.rtp.c_name);
794 EXPECT_EQ(0u, config.rtp.extensions.size());
795 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
796 config.send_transport);
797}
798
799// Test that we can add a receive stream and that it has the correct defaults.
800TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
801 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800802 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700803 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800804 GetRecvStreamConfig(kSsrcX);
805 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700806 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
807 EXPECT_FALSE(config.rtp.transport_cc);
808 EXPECT_EQ(0u, config.rtp.extensions.size());
809 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
810 config.rtcp_send_transport);
811 EXPECT_EQ("", config.sync_group);
812}
813
stefanba4c0e42016-02-04 04:12:24 -0800814TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700815 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800816 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100817 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800818 if (codec.name == "opus") {
819 EXPECT_TRUE(HasTransportCc(codec));
820 opus_found = true;
821 }
822 }
823 EXPECT_TRUE(opus_found);
824}
825
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826// Test that we set our inbound codecs properly, including changing PT.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800832 parameters.codecs.push_back(kTelephoneEventCodec1);
833 parameters.codecs.push_back(kTelephoneEventCodec2);
834 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200835 parameters.codecs[2].id = 126;
836 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800837 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700838 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
839 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
840 {{0, {"PCMU", 8000, 1}},
841 {106, {"ISAC", 16000, 1}},
842 {126, {"telephone-event", 8000, 1}},
843 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844}
845
846// Test that we fail to set an unknown inbound codec.
847TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700848 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200849 cricket::AudioRecvParameters parameters;
850 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700851 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that we fail if we have duplicate types in the inbound list.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kCn16000Codec);
861 parameters.codecs[1].id = kIsacCodec.id;
862 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
865// Test that we can decode OPUS without stereo parameters.
866TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700867 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200868 cricket::AudioRecvParameters parameters;
869 parameters.codecs.push_back(kIsacCodec);
870 parameters.codecs.push_back(kPcmuCodec);
871 parameters.codecs.push_back(kOpusCodec);
872 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800873 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700874 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
875 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
876 {{0, {"PCMU", 8000, 1}},
877 {103, {"ISAC", 16000, 1}},
878 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000879}
880
881// Test that we can decode OPUS with stereo = 0.
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
886 parameters.codecs.push_back(kPcmuCodec);
887 parameters.codecs.push_back(kOpusCodec);
888 parameters.codecs[2].params["stereo"] = "0";
889 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800890 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700891 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
892 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
893 {{0, {"PCMU", 8000, 1}},
894 {103, {"ISAC", 16000, 1}},
895 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
898// Test that we can decode OPUS with stereo = 1.
899TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700900 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200901 cricket::AudioRecvParameters parameters;
902 parameters.codecs.push_back(kIsacCodec);
903 parameters.codecs.push_back(kPcmuCodec);
904 parameters.codecs.push_back(kOpusCodec);
905 parameters.codecs[2].params["stereo"] = "1";
906 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800907 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700908 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
909 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
910 {{0, {"PCMU", 8000, 1}},
911 {103, {"ISAC", 16000, 1}},
912 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913}
914
915// Test that changes to recv codecs are applied to all streams.
916TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700917 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 cricket::AudioRecvParameters parameters;
919 parameters.codecs.push_back(kIsacCodec);
920 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800921 parameters.codecs.push_back(kTelephoneEventCodec1);
922 parameters.codecs.push_back(kTelephoneEventCodec2);
923 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 parameters.codecs[2].id = 126;
925 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700926 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
927 EXPECT_TRUE(AddRecvStream(ssrc));
928 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
929 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
930 {{0, {"PCMU", 8000, 1}},
931 {106, {"ISAC", 16000, 1}},
932 {126, {"telephone-event", 8000, 1}},
933 {107, {"telephone-event", 32000, 1}}})));
934 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935}
936
937TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 cricket::AudioRecvParameters parameters;
940 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800941 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
solenberg2100c0b2017-03-01 11:29:29 -0800944 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200945 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800946 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947}
948
949// Test that we can apply the same set of codecs again while playing.
950TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952 cricket::AudioRecvParameters parameters;
953 parameters.codecs.push_back(kIsacCodec);
954 parameters.codecs.push_back(kCn16000Codec);
955 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700956 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
deadbeefcb383672017-04-26 16:28:42 -0700959 // Remapping a payload type to a different codec should fail.
960 parameters.codecs[0] = kOpusCodec;
961 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800963 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
966// Test that we can add a codec while playing.
967TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200969 cricket::AudioRecvParameters parameters;
970 parameters.codecs.push_back(kIsacCodec);
971 parameters.codecs.push_back(kCn16000Codec);
972 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700973 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 parameters.codecs.push_back(kOpusCodec);
976 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800977 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978}
979
deadbeefcb383672017-04-26 16:28:42 -0700980// Test that we accept adding the same codec with a different payload type.
981// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
982TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
983 EXPECT_TRUE(SetupRecvStream());
984 cricket::AudioRecvParameters parameters;
985 parameters.codecs.push_back(kIsacCodec);
986 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
987
988 ++parameters.codecs[0].id;
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
990}
991
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700993 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000995 // Test that when autobw is enabled, bitrate is kept as the default
996 // value. autobw is enabled for the following tests because the target
997 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
999 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001000 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001003 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
ossu20a4b3f2017-04-27 02:08:52 -07001005 // opus, default bitrate == 32000 in mono.
1006 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007}
1008
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001009TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001010 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001013 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1014 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001015 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001018 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1019 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1020 // Rates above the max (510000) should be capped.
1021 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022}
1023
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001024TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001025 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001026
1027 // Test that we can only set a maximum bitrate for a fixed-rate codec
1028 // if it's bigger than the fixed rate.
1029
1030 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001031 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1032 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1033 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1034 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1035 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001038}
1039
1040TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001041 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001042 const int kDesiredBitrate = 128000;
1043 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001044 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001046 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001047
Yves Gerey665174f2018-06-19 15:03:05 +02001048 EXPECT_TRUE(
1049 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001050
solenberg2100c0b2017-03-01 11:29:29 -08001051 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001052}
1053
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054// Test that bitrate cannot be set for CBR codecs.
1055// Bitrate is ignored if it is higher than the fixed bitrate.
1056// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001057TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001058 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059
1060 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001061 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001062 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001063
1064 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001065 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001067
1068 send_parameters_.max_bandwidth_bps = 128;
1069 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071}
1072
skvlade0d46372016-04-07 22:59:22 -07001073// Test that the per-stream bitrate limit and the global
1074// bitrate limit both apply.
1075TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1076 EXPECT_TRUE(SetupSendStream());
1077
ossu20a4b3f2017-04-27 02:08:52 -07001078 // opus, default bitrate == 32000.
1079 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001080 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1081 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1082 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1083
1084 // CBR codecs allow both maximums to exceed the bitrate.
1085 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1086 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1087 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1088 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1089
1090 // CBR codecs don't allow per stream maximums to be too low.
1091 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1093}
1094
1095// Test that an attempt to set RtpParameters for a stream that does not exist
1096// fails.
1097TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1098 EXPECT_TRUE(SetupChannel());
1099 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001100 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001101 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001102
1103 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001104 EXPECT_FALSE(
1105 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001106}
1107
1108TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001109 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001110 // This test verifies that setting RtpParameters succeeds only if
1111 // the structure contains exactly one encoding.
1112 // TODO(skvlad): Update this test when we start supporting setting parameters
1113 // for each encoding individually.
1114
1115 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001116 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001117 // Two or more encodings should result in failure.
1118 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001119 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001120 // Zero encodings should also fail.
1121 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001122 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001123}
1124
1125// Changing the SSRC through RtpParameters is not allowed.
1126TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1127 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001128 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001129 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001130 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001131}
1132
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001133// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001134// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001135TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1136 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001137 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001138 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001140 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001141 ASSERT_EQ(1u, parameters.encodings.size());
1142 ASSERT_TRUE(parameters.encodings[0].active);
1143 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001144 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001145 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146
1147 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001148 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001149 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001150 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001151 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001152 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001153}
1154
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155// Test that SetRtpSendParameters configures the correct encoding channel for
1156// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001157TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1158 SetupForMultiSendStream();
1159 // Create send streams.
1160 for (uint32_t ssrc : kSsrcs4) {
1161 EXPECT_TRUE(
1162 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1163 }
1164 // Configure one stream to be limited by the stream config, another to be
1165 // limited by the global max, and the third one with no per-stream limit
1166 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001167 SetGlobalMaxBitrate(kOpusCodec, 32000);
1168 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1169 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001170 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1171
ossu20a4b3f2017-04-27 02:08:52 -07001172 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1173 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1174 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001175
1176 // Remove the global cap; the streams should switch to their respective
1177 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001178 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001179 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1180 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1181 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001182}
1183
Tim Haloun648d28a2018-10-18 16:52:22 -07001184// RTCRtpEncodingParameters.network_priority must be one of a few values
1185// derived from the default priority, corresponding to very-low, low, medium,
1186// or high.
1187TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1188 EXPECT_TRUE(SetupSendStream());
1189 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1190 EXPECT_EQ(1UL, parameters.encodings.size());
1191 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1192 parameters.encodings[0].network_priority);
1193
1194 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1195 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1196 for (auto it : good_values) {
1197 parameters.encodings[0].network_priority = it;
1198 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1199 }
1200 for (auto it : bad_values) {
1201 parameters.encodings[0].network_priority = it;
1202 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1203 }
1204}
1205
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001206// Test that GetRtpSendParameters returns the currently configured codecs.
1207TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001208 EXPECT_TRUE(SetupSendStream());
1209 cricket::AudioSendParameters parameters;
1210 parameters.codecs.push_back(kIsacCodec);
1211 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001212 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001213
solenberg2100c0b2017-03-01 11:29:29 -08001214 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001215 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001216 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1217 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218}
1219
Florent Castellidacec712018-05-24 16:24:21 +02001220// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1221TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1222 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1223 params.cname = "rtcpcname";
1224 EXPECT_TRUE(SetupSendStream(params));
1225
1226 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1227 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1228}
1229
Florent Castelliabe301f2018-06-12 18:33:49 +02001230TEST_F(WebRtcVoiceEngineTestFake,
1231 DetectRtpSendParameterHeaderExtensionsChange) {
1232 EXPECT_TRUE(SetupSendStream());
1233
1234 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1235 rtp_parameters.header_extensions.emplace_back();
1236
1237 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1238
1239 webrtc::RTCError result =
1240 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1241 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1242}
1243
deadbeefcb443432016-12-12 11:12:36 -08001244// Test that GetRtpSendParameters returns an SSRC.
1245TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1246 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001247 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001248 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001249 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001250}
1251
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001252// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001253TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001254 EXPECT_TRUE(SetupSendStream());
1255 cricket::AudioSendParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001258 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001259
solenberg2100c0b2017-03-01 11:29:29 -08001260 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001261
1262 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001263 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001265 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001266 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1267 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001268}
1269
minyuececec102017-03-27 13:04:25 -07001270// Test that max_bitrate_bps in send stream config gets updated correctly when
1271// SetRtpSendParameters is called.
1272TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1273 webrtc::test::ScopedFieldTrials override_field_trials(
1274 "WebRTC-Audio-SendSideBwe/Enabled/");
1275 EXPECT_TRUE(SetupSendStream());
1276 cricket::AudioSendParameters send_parameters;
1277 send_parameters.codecs.push_back(kOpusCodec);
1278 SetSendParameters(send_parameters);
1279
1280 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1281 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1282 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1283
1284 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001285 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001286 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001287
1288 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1289 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1290}
1291
Seth Hampson24722b32017-12-22 09:36:42 -08001292// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1293// a value <= 0, setting the parameters returns false.
1294TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1295 EXPECT_TRUE(SetupSendStream());
1296 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1297 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1298 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1299 rtp_parameters.encodings[0].bitrate_priority);
1300
1301 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001302 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001303 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001304 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001305}
1306
1307// Test that the bitrate_priority in the send stream config gets updated when
1308// SetRtpSendParameters is set for the VoiceMediaChannel.
1309TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1310 EXPECT_TRUE(SetupSendStream());
1311 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1312
1313 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1314 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1315 rtp_parameters.encodings[0].bitrate_priority);
1316 double new_bitrate_priority = 2.0;
1317 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001318 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001319
1320 // The priority should get set for both the audio channel's rtp parameters
1321 // and the audio send stream's audio config.
1322 EXPECT_EQ(
1323 new_bitrate_priority,
1324 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1325 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1326}
1327
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001328// Test that GetRtpReceiveParameters returns the currently configured codecs.
1329TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1330 EXPECT_TRUE(SetupRecvStream());
1331 cricket::AudioRecvParameters parameters;
1332 parameters.codecs.push_back(kIsacCodec);
1333 parameters.codecs.push_back(kPcmuCodec);
1334 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1335
1336 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001337 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001338 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1339 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1340 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1341}
1342
deadbeefcb443432016-12-12 11:12:36 -08001343// Test that GetRtpReceiveParameters returns an SSRC.
1344TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1345 EXPECT_TRUE(SetupRecvStream());
1346 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001347 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001348 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001349 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001350}
1351
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001352// Test that if we set/get parameters multiple times, we get the same results.
1353TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1354 EXPECT_TRUE(SetupRecvStream());
1355 cricket::AudioRecvParameters parameters;
1356 parameters.codecs.push_back(kIsacCodec);
1357 parameters.codecs.push_back(kPcmuCodec);
1358 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1359
1360 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001361 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001362
1363 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001364 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365
1366 // ... And this shouldn't change the params returned by
1367 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001368 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1369 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001370}
1371
deadbeef3bc15102017-04-20 19:25:07 -07001372// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1373// aren't signaled. It should return an empty "RtpEncodingParameters" when
1374// configured to receive an unsignaled stream and no packets have been received
1375// yet, and start returning the SSRC once a packet has been received.
1376TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1377 ASSERT_TRUE(SetupChannel());
1378 // Call necessary methods to configure receiving a default stream as
1379 // soon as it arrives.
1380 cricket::AudioRecvParameters parameters;
1381 parameters.codecs.push_back(kIsacCodec);
1382 parameters.codecs.push_back(kPcmuCodec);
1383 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1384
1385 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1386 // stream. Should return nothing.
1387 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1388
1389 // Set a sink for an unsignaled stream.
1390 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1391 // Value of "0" means "unsignaled stream".
1392 channel_->SetRawAudioSink(0, std::move(fake_sink));
1393
1394 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1395 // in this method means "unsignaled stream".
1396 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1397 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1398 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1399
1400 // Receive PCMU packet (SSRC=1).
1401 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1402
1403 // The |ssrc| member should still be unset.
1404 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1405 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1406 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1407}
1408
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409// Test that we apply codecs properly.
1410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kIsacCodec);
1414 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001415 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001417 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001419 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1420 EXPECT_EQ(96, send_codec_spec.payload_type);
1421 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1422 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1423 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001424 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001425 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
ossu20a4b3f2017-04-27 02:08:52 -07001428// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1429// AudioSendStream.
1430TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001431 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 cricket::AudioSendParameters parameters;
1433 parameters.codecs.push_back(kIsacCodec);
1434 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001435 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 parameters.codecs[0].id = 96;
1437 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001438 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001441 // Calling SetSendCodec again with same codec which is already set.
1442 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001444 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1448// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001449
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001450// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001452 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001453 cricket::AudioSendParameters parameters;
1454 parameters.codecs.push_back(kOpusCodec);
1455 parameters.codecs[0].bitrate = 0;
1456 parameters.codecs[0].clockrate = 50000;
1457 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458}
1459
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001460// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].bitrate = 0;
1466 parameters.codecs[0].channels = 0;
1467 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468}
1469
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001470// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001472 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 cricket::AudioSendParameters parameters;
1474 parameters.codecs.push_back(kOpusCodec);
1475 parameters.codecs[0].bitrate = 0;
1476 parameters.codecs[0].channels = 0;
1477 parameters.codecs[0].params["stereo"] = "1";
1478 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479}
1480
1481// Test that if channel is 1 for opus and there's no stereo, we fail.
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001483 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 cricket::AudioSendParameters parameters;
1485 parameters.codecs.push_back(kOpusCodec);
1486 parameters.codecs[0].bitrate = 0;
1487 parameters.codecs[0].channels = 1;
1488 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001489}
1490
1491// Test that if channel is 1 for opus and stereo=0, we fail.
1492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001493 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001494 cricket::AudioSendParameters parameters;
1495 parameters.codecs.push_back(kOpusCodec);
1496 parameters.codecs[0].bitrate = 0;
1497 parameters.codecs[0].channels = 1;
1498 parameters.codecs[0].params["stereo"] = "0";
1499 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001500}
1501
1502// Test that if channel is 1 for opus and stereo=1, we fail.
1503TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001504 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001505 cricket::AudioSendParameters parameters;
1506 parameters.codecs.push_back(kOpusCodec);
1507 parameters.codecs[0].bitrate = 0;
1508 parameters.codecs[0].channels = 1;
1509 parameters.codecs[0].params["stereo"] = "1";
1510 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511}
1512
ossu20a4b3f2017-04-27 02:08:52 -07001513// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001515 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001516 cricket::AudioSendParameters parameters;
1517 parameters.codecs.push_back(kOpusCodec);
1518 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001519 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001520 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001521}
1522
ossu20a4b3f2017-04-27 02:08:52 -07001523// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001525 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001526 cricket::AudioSendParameters parameters;
1527 parameters.codecs.push_back(kOpusCodec);
1528 parameters.codecs[0].bitrate = 0;
1529 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001531 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532}
1533
ossu20a4b3f2017-04-27 02:08:52 -07001534// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001540 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001543 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001544
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001546 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001547 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001548}
1549
ossu20a4b3f2017-04-27 02:08:52 -07001550// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].bitrate = 0;
1556 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001558 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
ossu20a4b3f2017-04-27 02:08:52 -07001561// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001567 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001568 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001569 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001570 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001571
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001572 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001574 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001575}
1576
ossu20a4b3f2017-04-27 02:08:52 -07001577// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001584 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1585 EXPECT_EQ(111, spec.payload_type);
1586 EXPECT_EQ(96000, spec.target_bitrate_bps);
1587 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001588 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001589 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001590}
1591
ossu20a4b3f2017-04-27 02:08:52 -07001592// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001594 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001595 cricket::AudioSendParameters parameters;
1596 parameters.codecs.push_back(kOpusCodec);
1597 parameters.codecs[0].bitrate = 30000;
1598 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001600 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601}
1602
ossu20a4b3f2017-04-27 02:08:52 -07001603// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001605 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters parameters;
1607 parameters.codecs.push_back(kOpusCodec);
1608 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001610 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
ossu20a4b3f2017-04-27 02:08:52 -07001613// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001615 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
1618 parameters.codecs[0].bitrate = 30000;
1619 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001620 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001621 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001622}
1623
stefan13f1a0a2016-11-30 07:22:58 -08001624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1625 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1626 200000);
1627}
1628
1629TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1630 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1631}
1632
1633TEST_F(WebRtcVoiceEngineTestFake,
1634 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1635 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1636}
1637
1638TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1639 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1640}
1641
Yves Gerey665174f2018-06-19 15:03:05 +02001642TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001643 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1644 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001645 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001646 // Setting max bitrate should keep previous min bitrate
1647 // Setting max bitrate should not reset start bitrate.
1648 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1649 SetSdpBitrateParameters(
1650 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1651 Field(&BitrateConstraints::start_bitrate_bps, -1),
1652 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001653 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001654}
1655
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001656// Test that we can enable NACK with opus as callee.
1657TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001658 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001659 cricket::AudioSendParameters parameters;
1660 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001661 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1662 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001663 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001665 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001667
Yves Gerey665174f2018-06-19 15:03:05 +02001668 EXPECT_TRUE(
1669 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001670}
1671
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672// Test that we can enable NACK on receive streams.
1673TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001674 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 cricket::AudioSendParameters parameters;
1677 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001678 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1679 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001682 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683}
1684
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685// Test that we can disable NACK on receive streams.
1686TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001691 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1692 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001695
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001696 parameters.codecs.clear();
1697 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700}
1701
1702// Test that NACK is enabled on a new receive stream.
1703TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001704 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 cricket::AudioSendParameters parameters;
1706 parameters.codecs.push_back(kIsacCodec);
1707 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001708 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1709 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711
solenberg2100c0b2017-03-01 11:29:29 -08001712 EXPECT_TRUE(AddRecvStream(kSsrcY));
1713 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1714 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1715 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716}
1717
stefanba4c0e42016-02-04 04:12:24 -08001718TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001719 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001720 cricket::AudioSendParameters send_parameters;
1721 send_parameters.codecs.push_back(kOpusCodec);
1722 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001724
1725 cricket::AudioRecvParameters recv_parameters;
1726 recv_parameters.codecs.push_back(kIsacCodec);
1727 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001728 EXPECT_TRUE(AddRecvStream(kSsrcX));
1729 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001730 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001731 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001732
ossudedfd282016-06-14 07:12:39 -07001733 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001735 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001736 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001737 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001738}
1739
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001740// Test that we can switch back and forth between Opus and ISAC with CN.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001743
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters opus_parameters;
1745 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001746 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001747 {
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(111, spec.payload_type);
1750 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001751 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001753 cricket::AudioSendParameters isac_parameters;
1754 isac_parameters.codecs.push_back(kIsacCodec);
1755 isac_parameters.codecs.push_back(kCn16000Codec);
1756 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001758 {
ossu20a4b3f2017-04-27 02:08:52 -07001759 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1760 EXPECT_EQ(103, spec.payload_type);
1761 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001765 {
ossu20a4b3f2017-04-27 02:08:52 -07001766 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1767 EXPECT_EQ(111, spec.payload_type);
1768 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001769 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770}
1771
1772// Test that we handle various ways of specifying bitrate.
1773TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001774 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 cricket::AudioSendParameters parameters;
1776 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001778 {
ossu20a4b3f2017-04-27 02:08:52 -07001779 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1780 EXPECT_EQ(103, spec.payload_type);
1781 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1782 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001783 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784
Yves Gerey665174f2018-06-19 15:03:05 +02001785 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001787 {
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(103, spec.payload_type);
1790 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1791 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001792 }
Yves Gerey665174f2018-06-19 15:03:05 +02001793 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001795 {
ossu20a4b3f2017-04-27 02:08:52 -07001796 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1797 EXPECT_EQ(103, spec.payload_type);
1798 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1799 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001800 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801
Yves Gerey665174f2018-06-19 15:03:05 +02001802 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001804 {
ossu20a4b3f2017-04-27 02:08:52 -07001805 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1806 EXPECT_EQ(0, spec.payload_type);
1807 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1808 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001809 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810
Yves Gerey665174f2018-06-19 15:03:05 +02001811 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001812 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001813 {
ossu20a4b3f2017-04-27 02:08:52 -07001814 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1815 EXPECT_EQ(0, spec.payload_type);
1816 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1817 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001818 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001820 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001821 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001822 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001823 {
ossu20a4b3f2017-04-27 02:08:52 -07001824 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1825 EXPECT_EQ(111, spec.payload_type);
1826 EXPECT_STREQ("opus", spec.format.name.c_str());
1827 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001828 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829}
1830
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001831// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001833 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 cricket::AudioSendParameters parameters;
1835 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001836}
1837
1838// Test that we can set send codecs even with telephone-event codec as the first
1839// one on the list.
1840TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001841 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001842 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001843 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 parameters.codecs.push_back(kIsacCodec);
1845 parameters.codecs.push_back(kPcmuCodec);
1846 parameters.codecs[0].id = 98; // DTMF
1847 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001848 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001849 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1850 EXPECT_EQ(96, spec.payload_type);
1851 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001852 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001853 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001854}
1855
Harald Alvestranda1f66612018-02-21 11:24:23 +01001856// Test that CanInsertDtmf() is governed by the send flag
1857TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1858 EXPECT_TRUE(SetupSendStream());
1859 cricket::AudioSendParameters parameters;
1860 parameters.codecs.push_back(kTelephoneEventCodec1);
1861 parameters.codecs.push_back(kPcmuCodec);
1862 parameters.codecs[0].id = 98; // DTMF
1863 parameters.codecs[1].id = 96;
1864 SetSendParameters(parameters);
1865 EXPECT_FALSE(channel_->CanInsertDtmf());
1866 SetSend(true);
1867 EXPECT_TRUE(channel_->CanInsertDtmf());
1868 SetSend(false);
1869 EXPECT_FALSE(channel_->CanInsertDtmf());
1870}
1871
solenberg31642aa2016-03-14 08:00:37 -07001872// Test that payload type range is limited for telephone-event codec.
1873TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001874 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001875 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001876 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001877 parameters.codecs.push_back(kIsacCodec);
1878 parameters.codecs[0].id = 0; // DTMF
1879 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001881 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001882 EXPECT_TRUE(channel_->CanInsertDtmf());
1883 parameters.codecs[0].id = 128; // DTMF
1884 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1885 EXPECT_FALSE(channel_->CanInsertDtmf());
1886 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001887 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001888 EXPECT_TRUE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = -1; // DTMF
1890 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1891 EXPECT_FALSE(channel_->CanInsertDtmf());
1892}
1893
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001894// Test that we can set send codecs even with CN codec as the first
1895// one on the list.
1896TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001897 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001898 cricket::AudioSendParameters parameters;
1899 parameters.codecs.push_back(kCn16000Codec);
1900 parameters.codecs.push_back(kIsacCodec);
1901 parameters.codecs.push_back(kPcmuCodec);
1902 parameters.codecs[0].id = 98; // wideband CN
1903 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001904 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001905 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1906 EXPECT_EQ(96, send_codec_spec.payload_type);
1907 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001908 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001909}
1910
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001911// Test that we set VAD and DTMF types correctly as caller.
1912TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001913 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 cricket::AudioSendParameters parameters;
1915 parameters.codecs.push_back(kIsacCodec);
1916 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 parameters.codecs.push_back(kCn16000Codec);
1919 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001920 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs[0].id = 96;
1922 parameters.codecs[2].id = 97; // wideband CN
1923 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001924 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001925 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1926 EXPECT_EQ(96, send_codec_spec.payload_type);
1927 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001928 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001929 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001930 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001931 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001932}
1933
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001934// Test that we set VAD and DTMF types correctly as callee.
1935TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001936 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 cricket::AudioSendParameters parameters;
1938 parameters.codecs.push_back(kIsacCodec);
1939 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001940 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 parameters.codecs.push_back(kCn16000Codec);
1942 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001943 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs[0].id = 96;
1945 parameters.codecs[2].id = 97; // wideband CN
1946 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001948 EXPECT_TRUE(
1949 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001950
ossu20a4b3f2017-04-27 02:08:52 -07001951 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1952 EXPECT_EQ(96, send_codec_spec.payload_type);
1953 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001954 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001955 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001956 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001957 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001958}
1959
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960// Test that we only apply VAD if we have a CN codec that matches the
1961// send codec clockrate.
1962TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001963 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001964 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001966 parameters.codecs.push_back(kIsacCodec);
1967 parameters.codecs.push_back(kCn16000Codec);
1968 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001969 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001970 {
ossu20a4b3f2017-04-27 02:08:52 -07001971 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1972 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001973 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001974 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001975 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001979 {
ossu20a4b3f2017-04-27 02:08:52 -07001980 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1981 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001982 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001983 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001984 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001985 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001987 {
ossu20a4b3f2017-04-27 02:08:52 -07001988 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1989 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001990 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001991 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001992 }
Brave Yao5225dd82015-03-26 07:39:19 +08001993 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001994 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001995 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001996 {
ossu20a4b3f2017-04-27 02:08:52 -07001997 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1998 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001999 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002000 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002001}
2002
2003// Test that we perform case-insensitive matching of codec names.
2004TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002005 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002006 cricket::AudioSendParameters parameters;
2007 parameters.codecs.push_back(kIsacCodec);
2008 parameters.codecs.push_back(kPcmuCodec);
2009 parameters.codecs.push_back(kCn16000Codec);
2010 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002011 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 parameters.codecs[0].name = "iSaC";
2013 parameters.codecs[0].id = 96;
2014 parameters.codecs[2].id = 97; // wideband CN
2015 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002017 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2018 EXPECT_EQ(96, send_codec_spec.payload_type);
2019 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002020 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002021 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002022 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002023 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002024}
2025
stefanba4c0e42016-02-04 04:12:24 -08002026class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2027 public:
2028 WebRtcVoiceEngineWithSendSideBweTest()
2029 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2030};
2031
2032TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2033 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002034 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2035 EXPECT_THAT(capabilities.header_extensions,
2036 Contains(testing::Field(
2037 "uri", &RtpExtension::uri,
2038 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002039}
2040
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002041// Test support for audio level header extension.
2042TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002043 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002044}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002045TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002046 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002047}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002048
solenbergd4adce42016-11-17 06:26:52 -08002049// Test support for transport sequence number header extension.
2050TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2051 TestSetSendRtpHeaderExtensions(
2052 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002053}
solenbergd4adce42016-11-17 06:26:52 -08002054TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2055 TestSetRecvRtpHeaderExtensions(
2056 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002057}
2058
solenberg1ac56142015-10-13 03:58:19 -07002059// Test that we can create a channel and start sending on it.
2060TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002061 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(send_parameters_);
2063 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002064 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002066 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002067}
2068
2069// Test that a channel will send if and only if it has a source and is enabled
2070// for sending.
2071TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002072 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002073 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002074 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002075 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002076 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2077 SetAudioSend(kSsrcX, true, &fake_source_);
2078 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2079 SetAudioSend(kSsrcX, true, nullptr);
2080 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002081}
2082
solenberg94218532016-06-16 10:53:22 -07002083// Test that a channel is muted/unmuted.
2084TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2085 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002086 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002087 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2088 SetAudioSend(kSsrcX, true, nullptr);
2089 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2090 SetAudioSend(kSsrcX, false, nullptr);
2091 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002092}
2093
solenberg6d6e7c52016-04-13 09:07:30 -07002094// Test that SetSendParameters() does not alter a stream's send state.
2095TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2096 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002098
2099 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002100 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002101 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002102
2103 // Changing RTP header extensions will recreate the AudioSendStream.
2104 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002105 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002106 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002107 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002108
2109 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002110 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002112
2113 // Changing RTP header extensions will recreate the AudioSendStream.
2114 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002115 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002117}
2118
solenberg1ac56142015-10-13 03:58:19 -07002119// Test that we can create a channel and start playing out on it.
2120TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002121 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002122 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002123 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002124 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002125 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002126 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127}
2128
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129// Test that we can add and remove send streams.
2130TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2131 SetupForMultiSendStream();
2132
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002134 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135
solenbergc96df772015-10-21 13:01:53 -07002136 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002137 EXPECT_TRUE(
2138 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002139 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002141 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142 }
tfarina5237aaf2015-11-10 23:44:30 -08002143 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144
solenbergc96df772015-10-21 13:01:53 -07002145 // Delete the send streams.
2146 for (uint32_t ssrc : kSsrcs4) {
2147 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002148 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002149 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150 }
solenbergc96df772015-10-21 13:01:53 -07002151 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152}
2153
2154// Test SetSendCodecs correctly configure the codecs in all send streams.
2155TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2156 SetupForMultiSendStream();
2157
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002159 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002160 EXPECT_TRUE(
2161 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162 }
2163
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002164 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002166 parameters.codecs.push_back(kIsacCodec);
2167 parameters.codecs.push_back(kCn16000Codec);
2168 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002169 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170
2171 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002172 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002173 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2174 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002175 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2176 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002177 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002178 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 }
2180
minyue7a973442016-10-20 03:27:12 -07002181 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002182 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002184 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002185 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2186 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002187 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2188 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002189 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
2191}
2192
2193// Test we can SetSend on all send streams correctly.
2194TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2195 SetupForMultiSendStream();
2196
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002197 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002198 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002199 EXPECT_TRUE(
2200 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002201 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 }
2204
2205 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002206 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002207 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002209 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002210 }
2211
2212 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002213 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002214 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002216 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002217 }
2218}
2219
2220// Test we can set the correct statistics on all send streams.
2221TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2222 SetupForMultiSendStream();
2223
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002225 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002226 EXPECT_TRUE(
2227 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 }
solenberg85a04962015-10-27 03:35:21 -07002229
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002230 // Create a receive stream to check that none of the send streams end up in
2231 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002232 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002233
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002234 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002236 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002237 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002238
solenberg85a04962015-10-27 03:35:21 -07002239 // Check stats for the added streams.
2240 {
2241 cricket::VoiceMediaInfo info;
2242 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002243
solenberg85a04962015-10-27 03:35:21 -07002244 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002245 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002246 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002247 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002248 }
hbos1acfbd22016-11-17 23:43:29 -08002249 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002250
2251 // We have added one receive stream. We should see empty stats.
2252 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002253 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002254 }
solenberg1ac56142015-10-13 03:58:19 -07002255
solenberg2100c0b2017-03-01 11:29:29 -08002256 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002257 {
2258 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002259 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002260 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002261 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002262 EXPECT_EQ(0u, info.receivers.size());
2263 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002264
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002265 // Deliver a new packet - a default receive stream should be created and we
2266 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002267 {
2268 cricket::VoiceMediaInfo info;
2269 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2270 SetAudioReceiveStreamStats();
2271 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002272 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002273 EXPECT_EQ(1u, info.receivers.size());
2274 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002275 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002276 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002277}
2278
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002279// Test that we can add and remove receive streams, and do proper send/playout.
2280// We can receive on multiple streams while sending one stream.
2281TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002282 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002283
solenberg1ac56142015-10-13 03:58:19 -07002284 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002285 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002286 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
solenberg1ac56142015-10-13 03:58:19 -07002288 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002290 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002291 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
solenberg1ac56142015-10-13 03:58:19 -07002293 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
2296 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2298 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2299 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300
2301 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002302 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002303 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304
2305 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002306 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002307 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2308 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002309
aleloi84ef6152016-08-04 05:28:21 -07002310 // Restart playout and make sure recv streams are played out.
2311 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002312 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2313 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002314
aleloi84ef6152016-08-04 05:28:21 -07002315 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2317 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002318}
2319
wu@webrtc.org97077a32013-10-25 21:18:33 +00002320TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002321 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002322 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002323 .Times(testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002324 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002325 const auto& agc_config = apm_config_.gain_controller1;
2326
2327 // Ensure default options.
2328 VerifyGainControlEnabledCorrectly();
2329 VerifyGainControlDefaultSettings();
2330
2331 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002332 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002333 EXPECT_FALSE(agc_config.enabled);
2334 send_parameters_.options.auto_gain_control = absl::nullopt;
2335
2336 send_parameters_.options.tx_agc_target_dbov = 5;
2337 SetSendParameters(send_parameters_);
2338 EXPECT_EQ(5, agc_config.target_level_dbfs);
2339 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2340
2341 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2342 SetSendParameters(send_parameters_);
2343 EXPECT_EQ(10, agc_config.compression_gain_db);
2344 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2345
2346 send_parameters_.options.tx_agc_limiter = false;
2347 SetSendParameters(send_parameters_);
2348 EXPECT_FALSE(agc_config.enable_limiter);
2349 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2350
2351 SetSendParameters(send_parameters_);
2352 // Expect all options to have been preserved.
2353 EXPECT_FALSE(agc_config.enabled);
2354 EXPECT_EQ(5, agc_config.target_level_dbfs);
2355 EXPECT_EQ(10, agc_config.compression_gain_db);
2356 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002357}
2358
minyue6b825df2016-10-31 04:08:32 -07002359TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2360 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002361 send_parameters_.options.audio_network_adaptor = true;
2362 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002363 SetSendParameters(send_parameters_);
2364 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002365 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002366}
2367
2368TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2369 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002370 send_parameters_.options.audio_network_adaptor = true;
2371 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002372 SetSendParameters(send_parameters_);
2373 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002374 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002375 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002376 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002377 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002378 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002379}
2380
2381TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2382 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002383 send_parameters_.options.audio_network_adaptor = true;
2384 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002385 SetSendParameters(send_parameters_);
2386 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002387 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002388 const int initial_num = call_.GetNumCreatedSendStreams();
2389 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002390 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002391 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2392 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002393 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002394 // AudioSendStream not expected to be recreated.
2395 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2396 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002397 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002398}
2399
michaelt6672b262017-01-11 10:17:59 -08002400class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2401 : public WebRtcVoiceEngineTestFake {
2402 public:
2403 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2404 : WebRtcVoiceEngineTestFake(
2405 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2406 "Enabled/") {}
2407};
2408
2409TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2410 EXPECT_TRUE(SetupSendStream());
2411 cricket::AudioSendParameters parameters;
2412 parameters.codecs.push_back(kOpusCodec);
2413 SetSendParameters(parameters);
2414 const int initial_num = call_.GetNumCreatedSendStreams();
2415 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2416
2417 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2418 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002419 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2420 constexpr int kMinOverheadBps =
2421 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002422
2423 constexpr int kOpusMinBitrateBps = 6000;
2424 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002425 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002426 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002427 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002428 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002429
Oskar Sundbom78807582017-11-16 11:09:55 +01002430 parameters.options.audio_network_adaptor = true;
2431 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002432 SetSendParameters(parameters);
2433
ossu11bfc532017-02-16 05:37:06 -08002434 constexpr int kMinOverheadWithAnaBps =
2435 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002436
2437 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002438 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002439
minyuececec102017-03-27 13:04:25 -07002440 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002441 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002442}
2443
minyuececec102017-03-27 13:04:25 -07002444// This test is similar to
2445// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2446// additional field trial.
2447TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2448 SetRtpSendParameterUpdatesMaxBitrate) {
2449 EXPECT_TRUE(SetupSendStream());
2450 cricket::AudioSendParameters send_parameters;
2451 send_parameters.codecs.push_back(kOpusCodec);
2452 SetSendParameters(send_parameters);
2453
2454 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2455 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2456 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2457
2458 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002459 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002460 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002461
2462 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2463#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2464 constexpr int kMinOverhead = 3333;
2465#else
2466 constexpr int kMinOverhead = 6666;
2467#endif
2468 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2469}
2470
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002472// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002474 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002475 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476}
2477
2478TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2479 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002480 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002481 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002482 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002484 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002485 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002486 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487
solenberg85a04962015-10-27 03:35:21 -07002488 // Check stats for the added streams.
2489 {
2490 cricket::VoiceMediaInfo info;
2491 EXPECT_EQ(true, channel_->GetStats(&info));
2492
2493 // We have added one send stream. We should see the stats we've set.
2494 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002495 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002496 // We have added one receive stream. We should see empty stats.
2497 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002498 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002499 }
solenberg1ac56142015-10-13 03:58:19 -07002500
solenberg566ef242015-11-06 15:34:49 -08002501 // Start sending - this affects some reported stats.
2502 {
2503 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002504 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002505 EXPECT_EQ(true, channel_->GetStats(&info));
2506 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002507 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002508 }
2509
solenberg2100c0b2017-03-01 11:29:29 -08002510 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002511 {
2512 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002513 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002514 EXPECT_EQ(true, channel_->GetStats(&info));
2515 EXPECT_EQ(1u, info.senders.size());
2516 EXPECT_EQ(0u, info.receivers.size());
2517 }
solenberg1ac56142015-10-13 03:58:19 -07002518
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002519 // Deliver a new packet - a default receive stream should be created and we
2520 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002521 {
2522 cricket::VoiceMediaInfo info;
2523 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2524 SetAudioReceiveStreamStats();
2525 EXPECT_EQ(true, channel_->GetStats(&info));
2526 EXPECT_EQ(1u, info.senders.size());
2527 EXPECT_EQ(1u, info.receivers.size());
2528 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002529 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002530 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531}
2532
2533// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002534// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002536 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002537 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2538 EXPECT_TRUE(AddRecvStream(kSsrcY));
2539 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540}
2541
2542// Test that the local SSRC is the same on sending and receiving channels if the
2543// receive channel is created before the send channel.
2544TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002545 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002546 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002547 EXPECT_TRUE(
2548 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002549 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2550 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002551}
2552
2553// Test that we can properly receive packets.
2554TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002555 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002556 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002558
Yves Gerey665174f2018-06-19 15:03:05 +02002559 EXPECT_TRUE(
2560 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002561}
2562
2563// Test that we can properly receive packets on multiple streams.
2564TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002565 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002566 const uint32_t ssrc1 = 1;
2567 const uint32_t ssrc2 = 2;
2568 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002569 EXPECT_TRUE(AddRecvStream(ssrc1));
2570 EXPECT_TRUE(AddRecvStream(ssrc2));
2571 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002572 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002573 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002574 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002575 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002576 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002577 }
mflodman3d7db262016-04-29 00:57:13 -07002578
2579 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2580 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2581 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2582
2583 EXPECT_EQ(s1.received_packets(), 0);
2584 EXPECT_EQ(s2.received_packets(), 0);
2585 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002586
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002587 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002588 EXPECT_EQ(s1.received_packets(), 0);
2589 EXPECT_EQ(s2.received_packets(), 0);
2590 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002591
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002592 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002593 EXPECT_EQ(s1.received_packets(), 1);
2594 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2595 EXPECT_EQ(s2.received_packets(), 0);
2596 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002597
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002598 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002599 EXPECT_EQ(s1.received_packets(), 1);
2600 EXPECT_EQ(s2.received_packets(), 1);
2601 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2602 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002603
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002604 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002605 EXPECT_EQ(s1.received_packets(), 1);
2606 EXPECT_EQ(s2.received_packets(), 1);
2607 EXPECT_EQ(s3.received_packets(), 1);
2608 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002609
mflodman3d7db262016-04-29 00:57:13 -07002610 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2611 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2612 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613}
2614
solenberg2100c0b2017-03-01 11:29:29 -08002615// Test that receiving on an unsignaled stream works (a stream is created).
2616TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002617 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002618 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002619
solenberg7e63ef02015-11-20 00:19:43 -08002620 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002621
Mirko Bonadeif859e552018-05-30 15:31:29 +02002622 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002623 EXPECT_TRUE(
2624 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002625}
2626
Seth Hampson5897a6e2018-04-03 11:16:33 -07002627// Tests that when we add a stream without SSRCs, but contains a stream_id
2628// that it is stored and its stream id is later used when the first packet
2629// arrives to properly create a receive stream with a sync label.
2630TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2631 const char kSyncLabel[] = "sync_label";
2632 EXPECT_TRUE(SetupChannel());
2633 cricket::StreamParams unsignaled_stream;
2634 unsignaled_stream.set_stream_ids({kSyncLabel});
2635 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2636 // The stream shouldn't have been created at this point because it doesn't
2637 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002638 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002639
2640 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2641
Mirko Bonadeif859e552018-05-30 15:31:29 +02002642 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002643 EXPECT_TRUE(
2644 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2645 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2646
2647 // Removing the unsignaled stream clears the cached parameters. If a new
2648 // default unsignaled receive stream is created it will not have a sync group.
2649 channel_->RemoveRecvStream(0);
2650 channel_->RemoveRecvStream(kSsrc1);
2651
2652 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2653
Mirko Bonadeif859e552018-05-30 15:31:29 +02002654 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002655 EXPECT_TRUE(
2656 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2657 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2658}
2659
solenberg2100c0b2017-03-01 11:29:29 -08002660// Test that receiving N unsignaled stream works (streams will be created), and
2661// that packets are forwarded to them all.
2662TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002664 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002665 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2666
solenberg2100c0b2017-03-01 11:29:29 -08002667 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002668 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002669 rtc::SetBE32(&packet[8], ssrc);
2670 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002671
solenberg2100c0b2017-03-01 11:29:29 -08002672 // Verify we have one new stream for each loop iteration.
2673 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002674 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2675 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002676 }
mflodman3d7db262016-04-29 00:57:13 -07002677
solenberg2100c0b2017-03-01 11:29:29 -08002678 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002679 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002680 rtc::SetBE32(&packet[8], ssrc);
2681 DeliverPacket(packet, sizeof(packet));
2682
solenbergebb349d2017-03-13 05:46:15 -07002683 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002684 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2685 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2686 }
2687
2688 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2689 constexpr uint32_t kAnotherSsrc = 667;
2690 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002691 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002692
2693 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002694 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002695 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002696 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002697 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2698 EXPECT_EQ(2, streams[i]->received_packets());
2699 }
2700 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2701 EXPECT_EQ(1, streams[i]->received_packets());
2702 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002703 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002704}
2705
solenberg2100c0b2017-03-01 11:29:29 -08002706// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002707// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002708TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002709 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002710 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002711 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2712
2713 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002714 const uint32_t signaled_ssrc = 1;
2715 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002716 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002717 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002718 EXPECT_TRUE(
2719 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002720 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002721
2722 // Note that the first unknown SSRC cannot be 0, because we only support
2723 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002724 const uint32_t unsignaled_ssrc = 7011;
2725 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002726 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002727 EXPECT_TRUE(
2728 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002729 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002730
2731 DeliverPacket(packet, sizeof(packet));
2732 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2733
2734 rtc::SetBE32(&packet[8], signaled_ssrc);
2735 DeliverPacket(packet, sizeof(packet));
2736 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002737 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002738}
2739
solenberg4904fb62017-02-17 12:01:14 -08002740// Two tests to verify that adding a receive stream with the same SSRC as a
2741// previously added unsignaled stream will only recreate underlying stream
2742// objects if the stream parameters have changed.
2743TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2744 EXPECT_TRUE(SetupChannel());
2745
2746 // Spawn unsignaled stream with SSRC=1.
2747 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002748 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002749 EXPECT_TRUE(
2750 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002751
2752 // Verify that the underlying stream object in Call is not recreated when a
2753 // stream with SSRC=1 is added.
2754 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002755 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002756 int audio_receive_stream_id = streams.front()->id();
2757 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002758 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002759 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2760}
2761
2762TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2763 EXPECT_TRUE(SetupChannel());
2764
2765 // Spawn unsignaled stream with SSRC=1.
2766 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002767 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002768 EXPECT_TRUE(
2769 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002770
2771 // Verify that the underlying stream object in Call *is* recreated when a
2772 // stream with SSRC=1 is added, and which has changed stream parameters.
2773 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002774 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002775 int audio_receive_stream_id = streams.front()->id();
2776 cricket::StreamParams stream_params;
2777 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002778 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002779 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002780 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002781 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2782}
2783
solenberg1ac56142015-10-13 03:58:19 -07002784// Test that AddRecvStream creates new stream.
2785TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002786 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002787 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788}
2789
2790// Test that after adding a recv stream, we do not decode more codecs than
2791// those previously passed into SetRecvCodecs.
2792TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002793 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002794 cricket::AudioRecvParameters parameters;
2795 parameters.codecs.push_back(kIsacCodec);
2796 parameters.codecs.push_back(kPcmuCodec);
2797 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002798 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002799 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2800 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2801 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802}
2803
2804// Test that we properly clean up any streams that were added, even if
2805// not explicitly removed.
2806TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002807 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002808 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002809 EXPECT_TRUE(AddRecvStream(1));
2810 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002811
Mirko Bonadeif859e552018-05-30 15:31:29 +02002812 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2813 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002814 delete channel_;
2815 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002816 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2817 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818}
2819
wu@webrtc.org78187522013-10-07 23:32:02 +00002820TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002821 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002822 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002823}
2824
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002825TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002826 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002827 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002828 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002829}
2830
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002831// Test the InsertDtmf on default send stream as caller.
2832TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002833 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002834}
2835
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002836// Test the InsertDtmf on default send stream as callee
2837TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002838 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002839}
2840
2841// Test the InsertDtmf on specified send stream as caller.
2842TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002843 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002844}
2845
2846// Test the InsertDtmf on specified send stream as callee.
2847TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002848 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849}
2850
Johannes Kron9190b822018-10-29 11:22:05 +01002851// Test propagation of extmap allow mixed setting.
2852TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2853 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2854}
2855TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2856 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2857}
2858TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2859 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2860}
2861TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2862 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2863}
2864
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002865TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002866 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002867 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002868 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2869 .Times(9)
2870 .WillRepeatedly(Return(false));
2871 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2872 .Times(4)
2873 .WillRepeatedly(Return(false));
2874 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2875 .Times(2)
2876 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002877
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002878 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002879 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002880
solenberg246b8172015-12-08 09:50:23 -08002881 // Nothing set in AudioOptions, so everything should be as default.
2882 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002883 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002884 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002885 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002886 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002887 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002888 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
Sam Zackrissonba502232019-01-04 10:36:48 +01002890 // Turn typing detection off.
2891 send_parameters_.options.typing_detection = false;
2892 SetSendParameters(send_parameters_);
2893 EXPECT_FALSE(IsTypingDetectionEnabled());
2894
2895 // Leave typing detection unchanged, but non-default.
2896 send_parameters_.options.typing_detection = absl::nullopt;
2897 SetSendParameters(send_parameters_);
2898 EXPECT_FALSE(IsTypingDetectionEnabled());
2899
2900 // Turn typing detection on.
2901 send_parameters_.options.typing_detection = true;
2902 SetSendParameters(send_parameters_);
2903 EXPECT_TRUE(IsTypingDetectionEnabled());
2904
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002906 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002907 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002908 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002909
2910 // Turn echo cancellation back on, with settings, and make sure
2911 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002912 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002913 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002914 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002916 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2917 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002918 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002919 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002920 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002921
2922 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002923 send_parameters_.options.delay_agnostic_aec = false;
2924 send_parameters_.options.extended_filter_aec = false;
2925 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002926 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002927 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002928
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002929 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002930 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002931 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002932 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002933
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002934 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002935 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002936 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002937 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002938 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002939
2940 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002941 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002942 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002943 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002944 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002946 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002947 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002948 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002949 send_parameters_.options.noise_suppression = false;
2950 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002951 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002952 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002953 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002954 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002955 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956
solenberg1ac56142015-10-13 03:58:19 -07002957 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002958 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002959 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002960 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002961 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002962 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002963}
2964
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002965TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002966 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002967 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2968 .Times(8)
2969 .WillRepeatedly(Return(false));
2970 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2971 .Times(8)
2972 .WillRepeatedly(Return(false));
2973 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2974 .Times(8)
2975 .WillRepeatedly(Return(false));
2976 EXPECT_CALL(adm_, RecordingIsInitialized())
2977 .Times(2)
2978 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002979 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2980 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peaha9cc40b2017-06-29 08:32:09 -07002981 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002982
kwiberg686a8ef2016-02-26 03:00:35 -08002983 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002984 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2985 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2986 cricket::AudioOptions(),
2987 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002988 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002989 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2990 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2991 cricket::AudioOptions(),
2992 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
2994 // Have to add a stream to make SetSend work.
2995 cricket::StreamParams stream1;
2996 stream1.ssrcs.push_back(1);
2997 channel1->AddSendStream(stream1);
2998 cricket::StreamParams stream2;
2999 stream2.ssrcs.push_back(2);
3000 channel2->AddSendStream(stream2);
3001
3002 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003003 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003004 parameters_options_all.options.echo_cancellation = true;
3005 parameters_options_all.options.auto_gain_control = true;
3006 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003007 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003008 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003009 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003010 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003011 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003012 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003013 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003014 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003015 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003016 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003017
3018 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003019 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003020 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003021 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003022 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003023 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003024 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003025 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003026 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003027 expected_options.echo_cancellation = true;
3028 expected_options.auto_gain_control = true;
3029 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003030 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031
3032 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003033 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003034 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003035 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003036 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003037 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003038 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003039 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003040 expected_options.echo_cancellation = true;
3041 expected_options.auto_gain_control = false;
3042 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003043 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003045 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003046 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003047 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003048 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003049 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003051 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003052 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003053 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003054 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003055 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003056
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003057 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003058 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003059 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003060 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003061 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003064 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3065 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003066 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3067 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003068 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003069 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003070 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003071 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003072 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003073 expected_options.echo_cancellation = true;
3074 expected_options.auto_gain_control = false;
3075 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003076 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077}
3078
wu@webrtc.orgde305012013-10-31 15:40:38 +00003079// This test verifies DSCP settings are properly applied on voice media channel.
3080TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003081 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003082 cricket::FakeNetworkInterface network_interface;
3083 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003084 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003085 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003086
peaha9cc40b2017-06-29 08:32:09 -07003087 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003088
Sebastian Jansson84848f22018-11-16 10:40:36 +01003089 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3090 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3091 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003092 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003093 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3094 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3095
3096 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003097 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3098 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3099 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003100 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003101 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3102
3103 // Create a send stream to configure
3104 EXPECT_TRUE(
3105 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3106 parameters = channel->GetRtpSendParameters(kSsrcZ);
3107 ASSERT_FALSE(parameters.encodings.empty());
3108
3109 // Various priorities map to various dscp values.
3110 parameters.encodings[0].network_priority = 4.0;
3111 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003112 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003113 parameters.encodings[0].network_priority = 0.5;
3114 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3115 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3116
3117 // A bad priority does not change the dscp value.
3118 parameters.encodings[0].network_priority = 0.0;
3119 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3120 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003121
Tim Haloun6ca98362018-09-17 17:06:08 -07003122 // Packets should also self-identify their dscp in PacketOptions.
3123 const uint8_t kData[10] = {0};
3124 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003125 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003126
nisse51542be2016-02-12 02:27:06 -08003127 // Verify that setting the option to false resets the
3128 // DiffServCodePoint.
3129 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003130 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3131 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3132 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003133 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003134 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3135 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3136
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003137 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003138}
3139
solenberg4bac9c52015-10-09 02:32:53 -07003140TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003141 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003142 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003143 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003144 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003145 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003146 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3147 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3148 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003149}
3150
solenberg2100c0b2017-03-01 11:29:29 -08003151TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003152 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003153
3154 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003155 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003156 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3157
3158 // Should remember the volume "2" which will be set on new unsignaled streams,
3159 // and also set the gain to 2 on existing unsignaled streams.
3160 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3161 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3162
3163 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3164 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3165 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3166 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3167 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3168 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3169
3170 // Setting gain with SSRC=0 should affect all unsignaled streams.
3171 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003172 if (kMaxUnsignaledRecvStreams > 1) {
3173 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3174 }
solenberg2100c0b2017-03-01 11:29:29 -08003175 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3176
3177 // Setting gain on an individual stream affects only that.
3178 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003179 if (kMaxUnsignaledRecvStreams > 1) {
3180 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3181 }
solenberg2100c0b2017-03-01 11:29:29 -08003182 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183}
3184
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003185TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3186 EXPECT_TRUE(SetupChannel());
3187 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3188 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3189
3190 cricket::StreamParams stream;
3191 stream.ssrcs.push_back(kSsrcY);
3192 EXPECT_TRUE(channel_->AddRecvStream(stream));
3193 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3194 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3195 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3196}
3197
3198TEST_F(WebRtcVoiceEngineTestFake,
3199 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3200 // Here base minimum delay is abbreviated to delay in comments for shortness.
3201 EXPECT_TRUE(SetupChannel());
3202
3203 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3204 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3205 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3206 // Check that it doesn't provide default values for unknown ssrc.
3207 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3208
3209 // Check that default value for unsignaled streams is 0.
3210 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3211
3212 // Should remember the delay 100 which will be set on new unsignaled streams,
3213 // and also set the delay to 100 on existing unsignaled streams.
3214 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3215 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3216 // Check that it doesn't provide default values for unknown ssrc.
3217 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3218
3219 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3220 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3221 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3222 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3223 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3224 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3225
3226 // Setting delay with SSRC=0 should affect all unsignaled streams.
3227 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3230 }
3231 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3232
3233 // Setting delay on an individual stream affects only that.
3234 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3237 }
3238 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3239 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3240 // Check that it doesn't provide default values for unknown ssrc.
3241 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3242}
3243
Seth Hampson845e8782018-03-02 11:34:10 -08003244TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003245 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003246 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003247
solenbergff976312016-03-30 23:28:51 -07003248 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003249 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003250 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003251 // Creating two channels to make sure that sync label is set properly for both
3252 // the default voice channel and following ones.
3253 EXPECT_TRUE(channel_->AddRecvStream(sp));
3254 sp.ssrcs[0] += 1;
3255 EXPECT_TRUE(channel_->AddRecvStream(sp));
3256
Mirko Bonadeif859e552018-05-30 15:31:29 +02003257 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003258 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003259 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003260 << "SyncGroup should be set based on stream id";
3261 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003262 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003263 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003264}
3265
solenberg3a941542015-11-16 07:34:50 -08003266// TODO(solenberg): Remove, once recv streams are configured through Call.
3267// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003268TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269 // Test that setting the header extensions results in the expected state
3270 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003271 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 ssrcs.push_back(223);
3273 ssrcs.push_back(224);
3274
solenbergff976312016-03-30 23:28:51 -07003275 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003276 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003277 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003278 EXPECT_TRUE(
3279 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003280 }
3281
Mirko Bonadeif859e552018-05-30 15:31:29 +02003282 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003283 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003284 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003285 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003286 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003287 }
3288
3289 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003290 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003291 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003292 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003293 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003294 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003295 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003296 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003297 EXPECT_NE(nullptr, s);
3298 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003299 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3300 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003301 for (const auto& s_ext : s_exts) {
3302 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003303 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003304 }
3305 }
3306 }
3307 }
3308
3309 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003310 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003311 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003312 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003313 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003314 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003315 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003316}
3317
3318TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3319 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003320 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003321 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003322 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003323 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3324 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003326 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003327
solenbergff976312016-03-30 23:28:51 -07003328 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003329 cricket::WebRtcVoiceMediaChannel* media_channel =
3330 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003331 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003332 EXPECT_TRUE(media_channel->AddRecvStream(
3333 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3334
Mirko Bonadeif859e552018-05-30 15:31:29 +02003335 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003336 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003337 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003338 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003339 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003340 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003341 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003342 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343}
Minyue2013aec2015-05-13 14:14:42 +02003344
solenberg0a617e22015-10-20 15:49:38 -07003345// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003346// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003347TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003348 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003349 EXPECT_TRUE(AddRecvStream(kSsrcY));
3350 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003351 EXPECT_TRUE(
3352 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003353 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3354 EXPECT_TRUE(AddRecvStream(kSsrcW));
3355 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003356}
3357
solenberg7602aab2016-11-14 11:30:07 -08003358TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3359 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003360 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003361 EXPECT_TRUE(
3362 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003363 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3364 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3365 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003366 EXPECT_TRUE(
3367 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003368 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3369 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003370}
stefan658910c2015-09-03 05:48:32 -07003371
deadbeef884f5852016-01-15 09:20:04 -08003372TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003373 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003374 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3375 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003376
3377 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003378 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3379 EXPECT_TRUE(AddRecvStream(kSsrcX));
3380 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003381
3382 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003383 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3384 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003385
3386 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003387 channel_->SetRawAudioSink(kSsrcX, nullptr);
3388 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003389}
3390
solenberg2100c0b2017-03-01 11:29:29 -08003391TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003392 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003393 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3394 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003395 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3396 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003397
3398 // Should be able to set a default sink even when no stream exists.
3399 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3400
solenberg2100c0b2017-03-01 11:29:29 -08003401 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3402 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003403 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003404 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003405
3406 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003407 channel_->SetRawAudioSink(kSsrc0, nullptr);
3408 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003409
3410 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003411 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3412 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003413
3414 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003415 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003416 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003417 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3418
3419 // Spawn another unsignaled stream - it should be assigned the default sink
3420 // and the previous unsignaled stream should lose it.
3421 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3422 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3423 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3424 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003425 if (kMaxUnsignaledRecvStreams > 1) {
3426 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3427 }
solenberg2100c0b2017-03-01 11:29:29 -08003428 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3429
3430 // Reset the default sink - the second unsignaled stream should lose it.
3431 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003432 if (kMaxUnsignaledRecvStreams > 1) {
3433 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3434 }
solenberg2100c0b2017-03-01 11:29:29 -08003435 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3436
3437 // Try setting the default sink while two streams exists.
3438 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003439 if (kMaxUnsignaledRecvStreams > 1) {
3440 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3441 }
solenberg2100c0b2017-03-01 11:29:29 -08003442 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3443
3444 // Try setting the sink for the first unsignaled stream using its known SSRC.
3445 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003446 if (kMaxUnsignaledRecvStreams > 1) {
3447 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3448 }
solenberg2100c0b2017-03-01 11:29:29 -08003449 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003450 if (kMaxUnsignaledRecvStreams > 1) {
3451 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3452 }
deadbeef884f5852016-01-15 09:20:04 -08003453}
3454
skvlad7a43d252016-03-22 15:32:27 -07003455// Test that, just like the video channel, the voice channel communicates the
3456// network state to the call.
3457TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003458 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003459
3460 EXPECT_EQ(webrtc::kNetworkUp,
3461 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3462 EXPECT_EQ(webrtc::kNetworkUp,
3463 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3464
3465 channel_->OnReadyToSend(false);
3466 EXPECT_EQ(webrtc::kNetworkDown,
3467 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3468 EXPECT_EQ(webrtc::kNetworkUp,
3469 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3470
3471 channel_->OnReadyToSend(true);
3472 EXPECT_EQ(webrtc::kNetworkUp,
3473 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3474 EXPECT_EQ(webrtc::kNetworkUp,
3475 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3476}
3477
aleloi18e0b672016-10-04 02:45:47 -07003478// Test that playout is still started after changing parameters
3479TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3480 SetupRecvStream();
3481 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003482 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003483
3484 // Changing RTP header extensions will recreate the AudioReceiveStream.
3485 cricket::AudioRecvParameters parameters;
3486 parameters.extensions.push_back(
3487 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3488 channel_->SetRecvParameters(parameters);
3489
solenberg2100c0b2017-03-01 11:29:29 -08003490 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003491}
3492
Zhi Huangfa266ef2017-12-13 10:27:46 -08003493// Tests when GetSources is called with non-existing ssrc, it will return an
3494// empty list of RtpSource without crashing.
3495TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3496 // Setup an recv stream with |kSsrcX|.
3497 SetupRecvStream();
3498 cricket::WebRtcVoiceMediaChannel* media_channel =
3499 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3500 // Call GetSources with |kSsrcY| which doesn't exist.
3501 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3502 EXPECT_EQ(0u, sources.size());
3503}
3504
stefan658910c2015-09-03 05:48:32 -07003505// Tests that the library initializes and shuts down properly.
3506TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003507 // If the VoiceEngine wants to gather available codecs early, that's fine but
3508 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003509 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3510 webrtc::CreateDefaultTaskQueueFactory();
henrika919dc2e2017-10-12 14:24:55 +02003511 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003512 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003513 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003514 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003515 task_queue_factory.get(), &adm,
3516 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003517 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003518 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003519 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003520 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003521 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003522 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3523 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3524 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003525 EXPECT_TRUE(channel != nullptr);
3526 delete channel;
solenbergff976312016-03-30 23:28:51 -07003527}
stefan658910c2015-09-03 05:48:32 -07003528
solenbergff976312016-03-30 23:28:51 -07003529// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003530TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003531 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3532 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -07003533 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003534 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003535 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003536 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003537 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003538 {
peaha9cc40b2017-06-29 08:32:09 -07003539 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003540 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003541 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003542 task_queue_factory.get(), &adm,
3543 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003544 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003545 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003546 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003547 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003548 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003549 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3550 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3551 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003552 EXPECT_TRUE(channel != nullptr);
3553 delete channel;
3554 }
stefan658910c2015-09-03 05:48:32 -07003555}
3556
ossu20a4b3f2017-04-27 02:08:52 -07003557// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3558TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003559 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3560 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003561 // TODO(ossu): Why are the payload types of codecs with non-static payload
3562 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003563 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003564 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003565 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003566 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003567 task_queue_factory.get(), &adm,
3568 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003569 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003570 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003571 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003572 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003573 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003574 (clockrate == 0 || codec.clockrate == clockrate);
3575 };
3576 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003577 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003578 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003579 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003580 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003581 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003582 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003583 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003584 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003585 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003586 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003587 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003588 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3589 // Remove these checks once both send and receive side assigns payload
3590 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003591 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003592 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003593 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003594 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003595 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003596 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003597 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003598 EXPECT_EQ(111, codec.id);
3599 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3600 EXPECT_EQ("10", codec.params.find("minptime")->second);
3601 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3602 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003603 }
3604 }
stefan658910c2015-09-03 05:48:32 -07003605}
3606
3607// Tests that VoE supports at least 32 channels
3608TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003609 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3610 webrtc::CreateDefaultTaskQueueFactory();
henrika919dc2e2017-10-12 14:24:55 +02003611 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003612 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003613 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003614 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003615 task_queue_factory.get(), &adm,
3616 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003617 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003618 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003619 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003620 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003621 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003622
3623 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003624 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003625 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003626 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3627 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3628 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003629 if (!channel)
3630 break;
stefan658910c2015-09-03 05:48:32 -07003631 channels[num_channels++] = channel;
3632 }
3633
Mirko Bonadeif859e552018-05-30 15:31:29 +02003634 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003635 EXPECT_EQ(expected, num_channels);
3636
3637 while (num_channels > 0) {
3638 delete channels[--num_channels];
3639 }
stefan658910c2015-09-03 05:48:32 -07003640}
3641
3642// Test that we set our preferred codecs properly.
3643TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003644 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3645 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003646 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3647 // - Check that our builtin codecs are usable by Channel.
3648 // - The codecs provided by the engine is usable by Channel.
3649 // It does not check that the codecs in the RecvParameters are actually
3650 // what we sent in - though it's probably reasonable to expect so, if
3651 // SetRecvParameters returns true.
3652 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003653 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003654 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003655 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003656 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003657 task_queue_factory.get(), &adm,
3658 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003659 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003660 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003661 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003662 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003663 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003664 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003665 cricket::AudioOptions(),
3666 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003667 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003668 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003669 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003670}
ossu9def8002017-02-09 05:14:32 -08003671
3672TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3673 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003674 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3675 {48000, 2, 16000, 10000, 20000}};
3676 spec1.info.allow_comfort_noise = false;
3677 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003678 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003679 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3680 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003681 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003682 specs.push_back(webrtc::AudioCodecSpec{
3683 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3684 {16000, 1, 13300}});
3685 specs.push_back(
3686 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3687 specs.push_back(
3688 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003689
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003690 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3691 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003692 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3693 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3694 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003695 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003696 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003697 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003698 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003699
peaha9cc40b2017-06-29 08:32:09 -07003700 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003701 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003702 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3703 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003704 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003705 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003706 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003707 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003708
3709 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3710 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003711 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3712 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3713 if (codecs.size() > index)
3714 return codecs[index];
3715 return missing_codec;
3716 };
ossu9def8002017-02-09 05:14:32 -08003717
3718 // Ensure the general codecs are generated first and in order.
3719 for (size_t i = 0; i != specs.size(); ++i) {
3720 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3721 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3722 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3723 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3724 }
3725
3726 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003727 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003728 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3729 for (size_t i = 0; i != codecs.size(); ++i) {
3730 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003731 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003732 codec.clockrate == format.clockrate_hz &&
3733 codec.channels == format.num_channels) {
3734 return rtc::checked_cast<int>(i);
3735 }
3736 }
3737 return -1;
3738 };
ossu9def8002017-02-09 05:14:32 -08003739
3740 // Ensure all supplementary codecs are generated last. Their internal ordering
3741 // is not important.
3742 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3743 const int num_specs = static_cast<int>(specs.size());
3744 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3745 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3746 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3747 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3748 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3749 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3750 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3751}