blob: 4ddcd433778bdc44febe31e5b8372489a6ebf27a [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010019#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "call/call.h"
21#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "media/base/fake_media_engine.h"
23#include "media/base/fake_network_interface.h"
24#include "media/base/fake_rtp.h"
25#include "media/base/media_constants.h"
26#include "media/engine/fake_webrtc_call.h"
27#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/audio_device/include/mock_audio_device.h"
29#include "modules/audio_processing/include/mock_audio_processing.h"
30#include "pc/channel.h"
31#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010033#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "test/field_trial.h"
35#include "test/gtest.h"
36#include "test/mock_audio_decoder_factory.h"
37#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
Elad Alon157540a2019-02-08 23:37:52 +010039using ::testing::_;
40using ::testing::ContainerEq;
41using ::testing::Contains;
42using ::testing::Field;
43using ::testing::Return;
44using ::testing::ReturnPointee;
45using ::testing::SaveArg;
46using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000047
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010049using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050
solenberg418b7d32017-06-13 00:38:27 -070051constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070052
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
54const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070055const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
57const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
59const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020060const cricket::AudioCodec kTelephoneEventCodec1(106,
61 "telephone-event",
62 8000,
63 0,
64 1);
65const cricket::AudioCodec kTelephoneEventCodec2(107,
66 "telephone-event",
67 32000,
68 0,
69 1);
solenberg2779bab2016-11-17 04:45:19 -080070
solenberg2100c0b2017-03-01 11:29:29 -080071const uint32_t kSsrc0 = 0;
72const uint32_t kSsrc1 = 1;
73const uint32_t kSsrcX = 0x99;
74const uint32_t kSsrcY = 0x17;
75const uint32_t kSsrcZ = 0x42;
76const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020077const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
solenberg971cab02016-06-14 10:02:41 -070079constexpr int kRtpHistoryMs = 5000;
80
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010081constexpr webrtc::AudioProcessing::Config::GainController1::Mode
82 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010083#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010084 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010085#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010086 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010087#endif
88
89constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
90 webrtc::NoiseSuppression::kHigh;
91
solenberg9a5f032222017-03-15 06:14:12 -070092void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
93 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010094
95 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010096 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010097 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010098 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070099#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200100 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200101 *adm,
102 SetPlayoutDevice(
103 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
104 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200105 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700106#else
107 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
108#endif // #if defined(WEBRTC_WIN)
109 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200110 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700111 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100112#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200113 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200114 *adm,
115 SetRecordingDevice(
116 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
117 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200118 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100119#else
120 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
121#endif // #if defined(WEBRTC_WIN)
122 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200123 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
124 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100125 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700126 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
127 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
128 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100129
130 // Teardown.
131 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
132 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
133 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
134 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200135 EXPECT_CALL(*adm, Release())
136 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100137 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700138}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200139} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140
solenbergff976312016-03-30 23:28:51 -0700141// Tests that our stub library "works".
142TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100143 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
144 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700145 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700146 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700147 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
148 new rtc::RefCountedObject<
149 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700150 webrtc::AudioProcessing::Config apm_config;
151 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
152 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200153 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700154 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700155 {
ossuc54071d2016-08-17 02:45:41 -0700156 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100157 task_queue_factory.get(), &adm,
158 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100159 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700160 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700161 }
solenbergff976312016-03-30 23:28:51 -0700162}
163
deadbeef884f5852016-01-15 09:20:04 -0800164class FakeAudioSink : public webrtc::AudioSinkInterface {
165 public:
166 void OnData(const Data& audio) override {}
167};
168
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800169class FakeAudioSource : public cricket::AudioSource {
170 void SetSink(Sink* sink) override {}
171};
172
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200173class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 public:
stefanba4c0e42016-02-04 04:12:24 -0800175 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
176
177 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100178 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
179 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700180 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700181 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100182 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700183 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800184 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700185 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800186 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700187 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
188 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200189 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700190 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800191 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100192 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700194 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800195 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700196 // factories. Those tests should probably be moved elsewhere.
197 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
198 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100199 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100200 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
201 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200207 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100209 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100210 VerifyGainControlEnabledCorrectly();
211 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
solenberg8189b022016-06-14 12:13:00 -0700213
solenbergff976312016-03-30 23:28:51 -0700214 bool SetupChannel() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200215 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100216 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
217 cricket::AudioOptions(),
218 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200219 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000220 }
solenberg8189b022016-06-14 12:13:00 -0700221
solenbergff976312016-03-30 23:28:51 -0700222 bool SetupRecvStream() {
223 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700224 return false;
225 }
solenberg2100c0b2017-03-01 11:29:29 -0800226 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700227 }
solenberg8189b022016-06-14 12:13:00 -0700228
solenbergff976312016-03-30 23:28:51 -0700229 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200230 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
231 }
232
233 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700234 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000235 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
Florent Castellidacec712018-05-24 16:24:21 +0200237 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800238 return false;
239 }
peaha9cc40b2017-06-29 08:32:09 -0700240 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800241 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 }
solenberg8189b022016-06-14 12:13:00 -0700243
244 bool AddRecvStream(uint32_t ssrc) {
245 EXPECT_TRUE(channel_);
246 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
247 }
248
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700250 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700251 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800252 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
253 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700254 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800255 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256 }
solenberg8189b022016-06-14 12:13:00 -0700257
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700259 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700260 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 }
solenberg8189b022016-06-14 12:13:00 -0700262
Yves Gerey665174f2018-06-19 15:03:05 +0200263 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100265 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
266 const auto* send_stream = call_.GetAudioSendStream(ssrc);
267 EXPECT_TRUE(send_stream);
268 return *send_stream;
269 }
270
deadbeef884f5852016-01-15 09:20:04 -0800271 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
272 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
273 EXPECT_TRUE(recv_stream);
274 return *recv_stream;
275 }
276
solenberg3a941542015-11-16 07:34:50 -0800277 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800278 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800279 }
280
solenberg7add0582015-11-20 09:59:34 -0800281 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800282 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800283 }
284
solenberg059fb442016-10-26 05:12:24 -0700285 void SetSend(bool enable) {
286 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700287 if (enable) {
288 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
289 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
290 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200291 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700292 }
solenberg059fb442016-10-26 05:12:24 -0700293 channel_->SetSend(enable);
294 }
295
296 void SetSendParameters(const cricket::AudioSendParameters& params) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200297 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenberg059fb442016-10-26 05:12:24 -0700298 ASSERT_TRUE(channel_);
299 EXPECT_TRUE(channel_->SetSendParameters(params));
300 }
301
Yves Gerey665174f2018-06-19 15:03:05 +0200302 void SetAudioSend(uint32_t ssrc,
303 bool enable,
304 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700305 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700306 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700307 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700308 if (enable && options) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200309 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
minyue6b825df2016-10-31 04:08:32 -0700310 }
311 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700312 }
313
Yves Gerey665174f2018-06-19 15:03:05 +0200314 void TestInsertDtmf(uint32_t ssrc,
315 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800316 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700317 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700319 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200321 EXPECT_TRUE(
322 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000323 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700326 SetSendParameters(send_parameters_);
327 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800329 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800330 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700331 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000333
334 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700335 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800336 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200337 EXPECT_TRUE(
338 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000339 }
340
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800342 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 // Test send.
345 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800346 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100347 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800348 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800349 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800350 EXPECT_EQ(codec.id, telephone_event.payload_type);
351 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100352 EXPECT_EQ(2, telephone_event.event_code);
353 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 }
355
Johannes Kron9190b822018-10-29 11:22:05 +0100356 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
357 // For a caller, the answer will be applied in set remote description
358 // where SetSendParameters() is called.
359 EXPECT_TRUE(SetupChannel());
360 EXPECT_TRUE(
361 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
362 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
363 SetSendParameters(send_parameters_);
364 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
365 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
366 }
367
368 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
369 // For a callee, the answer will be applied in set local description
370 // where SetExtmapAllowMixed() and AddSendStream() are called.
371 EXPECT_TRUE(SetupChannel());
372 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
373 EXPECT_TRUE(
374 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
375
376 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
377 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
378 }
379
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000380 // Test that send bandwidth is set correctly.
381 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000382 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
383 // |expected_result| is the expected result from SetMaxSendBandwidth().
384 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700385 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
386 int max_bitrate,
387 bool expected_result,
388 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200389 cricket::AudioSendParameters parameters;
390 parameters.codecs.push_back(codec);
391 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700392 if (expected_result) {
393 SetSendParameters(parameters);
394 } else {
395 EXPECT_FALSE(channel_->SetSendParameters(parameters));
396 }
solenberg2100c0b2017-03-01 11:29:29 -0800397 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 // Sets the per-stream maximum bitrate limit for the specified SSRC.
401 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700402 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700403 EXPECT_EQ(1UL, parameters.encodings.size());
404
Oskar Sundbom78807582017-11-16 11:09:55 +0100405 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800406 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700407 }
408
solenberg059fb442016-10-26 05:12:24 -0700409 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700410 cricket::AudioSendParameters send_parameters;
411 send_parameters.codecs.push_back(codec);
412 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700413 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700414 }
415
ossu20a4b3f2017-04-27 02:08:52 -0700416 void CheckSendCodecBitrate(int32_t ssrc,
417 const char expected_name[],
418 int expected_bitrate) {
419 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
420 EXPECT_EQ(expected_name, spec->format.name);
421 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700422 }
423
Danil Chapovalov00c71832018-06-15 15:58:38 +0200424 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700425 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700426 }
427
Danil Chapovalov00c71832018-06-15 15:58:38 +0200428 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
429 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700430 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
431 }
432
skvlade0d46372016-04-07 22:59:22 -0700433 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
434 int global_max,
435 int stream_max,
436 bool expected_result,
437 int expected_codec_bitrate) {
438 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800439 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700440
441 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700442 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800443 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700444
445 // Verify that reading back the parameters gives results
446 // consistent with the Set() result.
447 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800448 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700449 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
450 EXPECT_EQ(expected_result ? stream_max : -1,
451 resulting_parameters.encodings[0].max_bitrate_bps);
452
453 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800454 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700455 }
456
stefan13f1a0a2016-11-30 07:22:58 -0800457 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
458 int expected_min_bitrate_bps,
459 const char* start_bitrate_kbps,
460 int expected_start_bitrate_bps,
461 const char* max_bitrate_kbps,
462 int expected_max_bitrate_bps) {
463 EXPECT_TRUE(SetupSendStream());
464 auto& codecs = send_parameters_.codecs;
465 codecs.clear();
466 codecs.push_back(kOpusCodec);
467 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
468 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
469 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100470 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
471 SetSdpBitrateParameters(
472 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
473 expected_min_bitrate_bps),
474 Field(&BitrateConstraints::start_bitrate_bps,
475 expected_start_bitrate_bps),
476 Field(&BitrateConstraints::max_bitrate_bps,
477 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800478
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100479 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800480 }
481
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000482 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700483 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000484
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000487
488 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700489 send_parameters_.extensions.push_back(
490 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700491 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000493
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200495 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700496 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800497 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000498
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000499 // Ensure extension is set properly.
500 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700501 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700502 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
504 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
505 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000506
solenberg7add0582015-11-20 09:59:34 -0800507 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200508 EXPECT_TRUE(
509 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
511 call_.GetAudioSendStream(kSsrcY));
512 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
513 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
514 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000515
516 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200517 send_parameters_.codecs.push_back(kPcmuCodec);
518 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700519 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
521 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000522 }
523
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000524 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700525 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000527 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800528 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000529
530 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700531 recv_parameters_.extensions.push_back(
532 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800533 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800534 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000535
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000536 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800537 recv_parameters_.extensions.clear();
538 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800539 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000540
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000541 // Ensure extension is set properly.
542 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700543 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800544 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800545 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
546 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
547 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000548
solenberg7add0582015-11-20 09:59:34 -0800549 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800550 EXPECT_TRUE(AddRecvStream(kSsrcY));
551 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
552 call_.GetAudioReceiveStream(kSsrcY));
553 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
554 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
555 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000556
557 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800558 recv_parameters_.extensions.clear();
559 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800560 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
561 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000562 }
563
solenberg85a04962015-10-27 03:35:21 -0700564 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
565 webrtc::AudioSendStream::Stats stats;
566 stats.local_ssrc = 12;
567 stats.bytes_sent = 345;
568 stats.packets_sent = 678;
569 stats.packets_lost = 9012;
570 stats.fraction_lost = 34.56f;
571 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100572 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700573 stats.ext_seqnum = 789;
574 stats.jitter_ms = 12;
575 stats.rtt_ms = 345;
576 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100577 stats.apm_statistics.delay_median_ms = 234;
578 stats.apm_statistics.delay_standard_deviation_ms = 567;
579 stats.apm_statistics.echo_return_loss = 890;
580 stats.apm_statistics.echo_return_loss_enhancement = 1234;
581 stats.apm_statistics.residual_echo_likelihood = 0.432f;
582 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100583 stats.ana_statistics.bitrate_action_counter = 321;
584 stats.ana_statistics.channel_action_counter = 432;
585 stats.ana_statistics.dtx_action_counter = 543;
586 stats.ana_statistics.fec_action_counter = 654;
587 stats.ana_statistics.frame_length_increase_counter = 765;
588 stats.ana_statistics.frame_length_decrease_counter = 876;
589 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700590 stats.typing_noise_detected = true;
591 return stats;
592 }
593 void SetAudioSendStreamStats() {
594 for (auto* s : call_.GetAudioSendStreams()) {
595 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200596 }
solenberg85a04962015-10-27 03:35:21 -0700597 }
solenberg566ef242015-11-06 15:34:49 -0800598 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
599 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700600 const auto stats = GetAudioSendStreamStats();
601 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
602 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
603 EXPECT_EQ(info.packets_sent, stats.packets_sent);
604 EXPECT_EQ(info.packets_lost, stats.packets_lost);
605 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
606 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800607 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700608 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
609 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
610 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
611 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100612 EXPECT_EQ(info.apm_statistics.delay_median_ms,
613 stats.apm_statistics.delay_median_ms);
614 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
615 stats.apm_statistics.delay_standard_deviation_ms);
616 EXPECT_EQ(info.apm_statistics.echo_return_loss,
617 stats.apm_statistics.echo_return_loss);
618 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
619 stats.apm_statistics.echo_return_loss_enhancement);
620 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
621 stats.apm_statistics.residual_echo_likelihood);
622 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
623 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700624 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
625 stats.ana_statistics.bitrate_action_counter);
626 EXPECT_EQ(info.ana_statistics.channel_action_counter,
627 stats.ana_statistics.channel_action_counter);
628 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
629 stats.ana_statistics.dtx_action_counter);
630 EXPECT_EQ(info.ana_statistics.fec_action_counter,
631 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700632 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
633 stats.ana_statistics.frame_length_increase_counter);
634 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
635 stats.ana_statistics.frame_length_decrease_counter);
636 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
637 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800638 EXPECT_EQ(info.typing_noise_detected,
639 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700640 }
641
642 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
643 webrtc::AudioReceiveStream::Stats stats;
644 stats.remote_ssrc = 123;
645 stats.bytes_rcvd = 456;
646 stats.packets_rcvd = 768;
647 stats.packets_lost = 101;
648 stats.fraction_lost = 23.45f;
649 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100650 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700651 stats.ext_seqnum = 678;
652 stats.jitter_ms = 901;
653 stats.jitter_buffer_ms = 234;
654 stats.jitter_buffer_preferred_ms = 567;
655 stats.delay_estimate_ms = 890;
656 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700657 stats.total_samples_received = 5678901;
658 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200659 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200660 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100661 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700662 stats.expand_rate = 5.67f;
663 stats.speech_expand_rate = 8.90f;
664 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200665 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700666 stats.accelerate_rate = 4.56f;
667 stats.preemptive_expand_rate = 7.89f;
668 stats.decoding_calls_to_silence_generator = 12;
669 stats.decoding_calls_to_neteq = 345;
670 stats.decoding_normal = 67890;
671 stats.decoding_plc = 1234;
672 stats.decoding_cng = 5678;
673 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700674 stats.decoding_muted_output = 3456;
675 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200676 return stats;
677 }
678 void SetAudioReceiveStreamStats() {
679 for (auto* s : call_.GetAudioReceiveStreams()) {
680 s->SetStats(GetAudioReceiveStreamStats());
681 }
682 }
683 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700684 const auto stats = GetAudioReceiveStreamStats();
685 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
686 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200687 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
688 stats.packets_rcvd);
689 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
690 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700691 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
692 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800693 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
695 stats.ext_seqnum);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
698 stats.jitter_buffer_ms);
699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700700 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
702 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700703 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700704 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
705 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200706 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200707 EXPECT_EQ(info.jitter_buffer_delay_seconds,
708 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100709 EXPECT_EQ(info.jitter_buffer_emitted_count,
710 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700711 EXPECT_EQ(info.expand_rate, stats.expand_rate);
712 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
713 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200714 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700715 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
716 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200717 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700718 stats.decoding_calls_to_silence_generator);
719 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
720 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
721 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
722 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
723 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700724 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700725 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200726 }
hbos1acfbd22016-11-17 23:43:29 -0800727 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
728 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
729 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
730 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
731 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
732 codec.ToCodecParameters());
733 }
734 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
735 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
736 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
737 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
738 codec.ToCodecParameters());
739 }
740 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200741
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100742 void VerifyGainControlEnabledCorrectly() {
743 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
744 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
745 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
746 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
747 }
748
749 void VerifyGainControlDefaultSettings() {
750 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
751 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
752 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
753 }
754
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200755 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100756 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200757 }
758
peah8271d042016-11-22 07:24:52 -0800759 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100760 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800761 }
762
Sam Zackrissonba502232019-01-04 10:36:48 +0100763 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100764 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100765 }
766
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100768 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700769 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700770 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800771 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200772 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700773 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700774 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioSendParameters send_parameters_;
776 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800777 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700778 webrtc::AudioProcessing::Config apm_config_;
779
stefanba4c0e42016-02-04 04:12:24 -0800780 private:
781 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782};
783
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100785TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700786 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787}
788
solenberg31fec402016-05-06 02:13:12 -0700789// Test that we can add a send stream and that it has the correct defaults.
790TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
791 EXPECT_TRUE(SetupChannel());
792 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800793 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
794 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
795 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700796 EXPECT_EQ("", config.rtp.c_name);
797 EXPECT_EQ(0u, config.rtp.extensions.size());
798 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
799 config.send_transport);
800}
801
802// Test that we can add a receive stream and that it has the correct defaults.
803TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
804 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800805 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700806 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800807 GetRecvStreamConfig(kSsrcX);
808 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700809 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
810 EXPECT_FALSE(config.rtp.transport_cc);
811 EXPECT_EQ(0u, config.rtp.extensions.size());
812 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
813 config.rtcp_send_transport);
814 EXPECT_EQ("", config.sync_group);
815}
816
stefanba4c0e42016-02-04 04:12:24 -0800817TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700818 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800819 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100820 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800821 if (codec.name == "opus") {
822 EXPECT_TRUE(HasTransportCc(codec));
823 opus_found = true;
824 }
825 }
826 EXPECT_TRUE(opus_found);
827}
828
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829// Test that we set our inbound codecs properly, including changing PT.
830TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200832 cricket::AudioRecvParameters parameters;
833 parameters.codecs.push_back(kIsacCodec);
834 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800835 parameters.codecs.push_back(kTelephoneEventCodec1);
836 parameters.codecs.push_back(kTelephoneEventCodec2);
837 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200838 parameters.codecs[2].id = 126;
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700841 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
842 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
843 {{0, {"PCMU", 8000, 1}},
844 {106, {"ISAC", 16000, 1}},
845 {126, {"telephone-event", 8000, 1}},
846 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
849// Test that we fail to set an unknown inbound codec.
850TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700851 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 cricket::AudioRecvParameters parameters;
853 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700854 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we fail if we have duplicate types in the inbound list.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kCn16000Codec);
864 parameters.codecs[1].id = kIsacCodec.id;
865 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866}
867
868// Test that we can decode OPUS without stereo parameters.
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 cricket::AudioRecvParameters parameters;
872 parameters.codecs.push_back(kIsacCodec);
873 parameters.codecs.push_back(kPcmuCodec);
874 parameters.codecs.push_back(kOpusCodec);
875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800876 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700877 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
878 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
879 {{0, {"PCMU", 8000, 1}},
880 {103, {"ISAC", 16000, 1}},
881 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882}
883
884// Test that we can decode OPUS with stereo = 0.
885TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700886 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 cricket::AudioRecvParameters parameters;
888 parameters.codecs.push_back(kIsacCodec);
889 parameters.codecs.push_back(kPcmuCodec);
890 parameters.codecs.push_back(kOpusCodec);
891 parameters.codecs[2].params["stereo"] = "0";
892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800893 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700894 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
895 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
896 {{0, {"PCMU", 8000, 1}},
897 {103, {"ISAC", 16000, 1}},
898 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899}
900
901// Test that we can decode OPUS with stereo = 1.
902TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700903 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 cricket::AudioRecvParameters parameters;
905 parameters.codecs.push_back(kIsacCodec);
906 parameters.codecs.push_back(kPcmuCodec);
907 parameters.codecs.push_back(kOpusCodec);
908 parameters.codecs[2].params["stereo"] = "1";
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700911 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
912 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
913 {{0, {"PCMU", 8000, 1}},
914 {103, {"ISAC", 16000, 1}},
915 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916}
917
918// Test that changes to recv codecs are applied to all streams.
919TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700920 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 cricket::AudioRecvParameters parameters;
922 parameters.codecs.push_back(kIsacCodec);
923 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800924 parameters.codecs.push_back(kTelephoneEventCodec1);
925 parameters.codecs.push_back(kTelephoneEventCodec2);
926 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200927 parameters.codecs[2].id = 126;
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700929 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
930 EXPECT_TRUE(AddRecvStream(ssrc));
931 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
932 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
933 {{0, {"PCMU", 8000, 1}},
934 {106, {"ISAC", 16000, 1}},
935 {126, {"telephone-event", 8000, 1}},
936 {107, {"telephone-event", 32000, 1}}})));
937 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
940TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700941 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 cricket::AudioRecvParameters parameters;
943 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800944 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
solenberg2100c0b2017-03-01 11:29:29 -0800947 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200948 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800949 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
952// Test that we can apply the same set of codecs again while playing.
953TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 cricket::AudioRecvParameters parameters;
956 parameters.codecs.push_back(kIsacCodec);
957 parameters.codecs.push_back(kCn16000Codec);
958 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700959 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
deadbeefcb383672017-04-26 16:28:42 -0700962 // Remapping a payload type to a different codec should fail.
963 parameters.codecs[0] = kOpusCodec;
964 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800966 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
969// Test that we can add a codec while playing.
970TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200972 cricket::AudioRecvParameters parameters;
973 parameters.codecs.push_back(kIsacCodec);
974 parameters.codecs.push_back(kCn16000Codec);
975 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700976 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 parameters.codecs.push_back(kOpusCodec);
979 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800980 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
deadbeefcb383672017-04-26 16:28:42 -0700983// Test that we accept adding the same codec with a different payload type.
984// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
985TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
986 EXPECT_TRUE(SetupRecvStream());
987 cricket::AudioRecvParameters parameters;
988 parameters.codecs.push_back(kIsacCodec);
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
990
991 ++parameters.codecs[0].id;
992 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
993}
994
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700996 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998 // Test that when autobw is enabled, bitrate is kept as the default
999 // value. autobw is enabled for the following tests because the target
1000 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001003 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
ossu20a4b3f2017-04-27 02:08:52 -07001008 // opus, default bitrate == 32000 in mono.
1009 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010}
1011
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001013 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001016 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1017 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001018 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001021 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1022 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1023 // Rates above the max (510000) should be capped.
1024 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025}
1026
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001027TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001028 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001029
1030 // Test that we can only set a maximum bitrate for a fixed-rate codec
1031 // if it's bigger than the fixed rate.
1032
1033 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001034 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1035 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001041}
1042
1043TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001044 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 const int kDesiredBitrate = 128000;
1046 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001047 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001048 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001049 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001050
Yves Gerey665174f2018-06-19 15:03:05 +02001051 EXPECT_TRUE(
1052 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001053
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001055}
1056
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057// Test that bitrate cannot be set for CBR codecs.
1058// Bitrate is ignored if it is higher than the fixed bitrate.
1059// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001060TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001061 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062
1063 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001064 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001066
1067 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001068 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001070
1071 send_parameters_.max_bandwidth_bps = 128;
1072 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001073 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074}
1075
skvlade0d46372016-04-07 22:59:22 -07001076// Test that the per-stream bitrate limit and the global
1077// bitrate limit both apply.
1078TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1079 EXPECT_TRUE(SetupSendStream());
1080
ossu20a4b3f2017-04-27 02:08:52 -07001081 // opus, default bitrate == 32000.
1082 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001083 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1084 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1085 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1086
1087 // CBR codecs allow both maximums to exceed the bitrate.
1088 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1089 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1090 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1092
1093 // CBR codecs don't allow per stream maximums to be too low.
1094 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1095 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1096}
1097
1098// Test that an attempt to set RtpParameters for a stream that does not exist
1099// fails.
1100TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1101 EXPECT_TRUE(SetupChannel());
1102 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001103 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001104 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001105
1106 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_FALSE(
1108 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001109}
1110
1111TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001113 // This test verifies that setting RtpParameters succeeds only if
1114 // the structure contains exactly one encoding.
1115 // TODO(skvlad): Update this test when we start supporting setting parameters
1116 // for each encoding individually.
1117
1118 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001119 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001120 // Two or more encodings should result in failure.
1121 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001122 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001123 // Zero encodings should also fail.
1124 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001125 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001126}
1127
1128// Changing the SSRC through RtpParameters is not allowed.
1129TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1130 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001132 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001133 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001134}
1135
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001136// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001137// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001138TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1139 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001140 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001141 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001142 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 ASSERT_EQ(1u, parameters.encodings.size());
1145 ASSERT_TRUE(parameters.encodings[0].active);
1146 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001147 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001148 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001149
1150 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001151 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001152 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001153 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001154 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001155 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001156}
1157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158// Test that SetRtpSendParameters configures the correct encoding channel for
1159// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001160TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1161 SetupForMultiSendStream();
1162 // Create send streams.
1163 for (uint32_t ssrc : kSsrcs4) {
1164 EXPECT_TRUE(
1165 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1166 }
1167 // Configure one stream to be limited by the stream config, another to be
1168 // limited by the global max, and the third one with no per-stream limit
1169 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001170 SetGlobalMaxBitrate(kOpusCodec, 32000);
1171 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1172 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1174
ossu20a4b3f2017-04-27 02:08:52 -07001175 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1176 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1177 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001178
1179 // Remove the global cap; the streams should switch to their respective
1180 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001181 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001182 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1183 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1184 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001185}
1186
Tim Haloun648d28a2018-10-18 16:52:22 -07001187// RTCRtpEncodingParameters.network_priority must be one of a few values
1188// derived from the default priority, corresponding to very-low, low, medium,
1189// or high.
1190TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1191 EXPECT_TRUE(SetupSendStream());
1192 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1193 EXPECT_EQ(1UL, parameters.encodings.size());
1194 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1195 parameters.encodings[0].network_priority);
1196
1197 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1198 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1199 for (auto it : good_values) {
1200 parameters.encodings[0].network_priority = it;
1201 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1202 }
1203 for (auto it : bad_values) {
1204 parameters.encodings[0].network_priority = it;
1205 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1206 }
1207}
1208
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209// Test that GetRtpSendParameters returns the currently configured codecs.
1210TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001211 EXPECT_TRUE(SetupSendStream());
1212 cricket::AudioSendParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001215 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001216
solenberg2100c0b2017-03-01 11:29:29 -08001217 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001219 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1220 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221}
1222
Florent Castellidacec712018-05-24 16:24:21 +02001223// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1224TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1225 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1226 params.cname = "rtcpcname";
1227 EXPECT_TRUE(SetupSendStream(params));
1228
1229 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1230 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1231}
1232
Florent Castelliabe301f2018-06-12 18:33:49 +02001233TEST_F(WebRtcVoiceEngineTestFake,
1234 DetectRtpSendParameterHeaderExtensionsChange) {
1235 EXPECT_TRUE(SetupSendStream());
1236
1237 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1238 rtp_parameters.header_extensions.emplace_back();
1239
1240 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1241
1242 webrtc::RTCError result =
1243 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1244 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1245}
1246
deadbeefcb443432016-12-12 11:12:36 -08001247// Test that GetRtpSendParameters returns an SSRC.
1248TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1249 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001250 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001251 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001252 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001253}
1254
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001255// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001256TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257 EXPECT_TRUE(SetupSendStream());
1258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kIsacCodec);
1260 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001261 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001262
solenberg2100c0b2017-03-01 11:29:29 -08001263 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
1265 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001266 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001267
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001268 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001269 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1270 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001271}
1272
minyuececec102017-03-27 13:04:25 -07001273// Test that max_bitrate_bps in send stream config gets updated correctly when
1274// SetRtpSendParameters is called.
1275TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1276 webrtc::test::ScopedFieldTrials override_field_trials(
1277 "WebRTC-Audio-SendSideBwe/Enabled/");
1278 EXPECT_TRUE(SetupSendStream());
1279 cricket::AudioSendParameters send_parameters;
1280 send_parameters.codecs.push_back(kOpusCodec);
1281 SetSendParameters(send_parameters);
1282
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1284 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1285 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1286
1287 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001288 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001289 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001290
1291 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1292 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1293}
1294
Seth Hampson24722b32017-12-22 09:36:42 -08001295// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1296// a value <= 0, setting the parameters returns false.
1297TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1298 EXPECT_TRUE(SetupSendStream());
1299 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1300 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1301 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1302 rtp_parameters.encodings[0].bitrate_priority);
1303
1304 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001305 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001306 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001307 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001308}
1309
1310// Test that the bitrate_priority in the send stream config gets updated when
1311// SetRtpSendParameters is set for the VoiceMediaChannel.
1312TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1313 EXPECT_TRUE(SetupSendStream());
1314 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1315
1316 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1317 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1318 rtp_parameters.encodings[0].bitrate_priority);
1319 double new_bitrate_priority = 2.0;
1320 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001321 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001322
1323 // The priority should get set for both the audio channel's rtp parameters
1324 // and the audio send stream's audio config.
1325 EXPECT_EQ(
1326 new_bitrate_priority,
1327 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1328 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1329}
1330
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001331// Test that GetRtpReceiveParameters returns the currently configured codecs.
1332TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1333 EXPECT_TRUE(SetupRecvStream());
1334 cricket::AudioRecvParameters parameters;
1335 parameters.codecs.push_back(kIsacCodec);
1336 parameters.codecs.push_back(kPcmuCodec);
1337 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1338
1339 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001340 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001341 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1342 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1343 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1344}
1345
deadbeefcb443432016-12-12 11:12:36 -08001346// Test that GetRtpReceiveParameters returns an SSRC.
1347TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1348 EXPECT_TRUE(SetupRecvStream());
1349 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001350 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001351 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001352 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001353}
1354
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001355// Test that if we set/get parameters multiple times, we get the same results.
1356TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1357 EXPECT_TRUE(SetupRecvStream());
1358 cricket::AudioRecvParameters parameters;
1359 parameters.codecs.push_back(kIsacCodec);
1360 parameters.codecs.push_back(kPcmuCodec);
1361 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1362
1363 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001364 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365
1366 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001367 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001368
1369 // ... And this shouldn't change the params returned by
1370 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001371 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1372 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001373}
1374
deadbeef3bc15102017-04-20 19:25:07 -07001375// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1376// aren't signaled. It should return an empty "RtpEncodingParameters" when
1377// configured to receive an unsignaled stream and no packets have been received
1378// yet, and start returning the SSRC once a packet has been received.
1379TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1380 ASSERT_TRUE(SetupChannel());
1381 // Call necessary methods to configure receiving a default stream as
1382 // soon as it arrives.
1383 cricket::AudioRecvParameters parameters;
1384 parameters.codecs.push_back(kIsacCodec);
1385 parameters.codecs.push_back(kPcmuCodec);
1386 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1387
1388 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1389 // stream. Should return nothing.
1390 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1391
1392 // Set a sink for an unsignaled stream.
1393 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1394 // Value of "0" means "unsignaled stream".
1395 channel_->SetRawAudioSink(0, std::move(fake_sink));
1396
1397 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1398 // in this method means "unsignaled stream".
1399 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1400 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1401 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1402
1403 // Receive PCMU packet (SSRC=1).
1404 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1405
1406 // The |ssrc| member should still be unset.
1407 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1408 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1409 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1410}
1411
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412// Test that we apply codecs properly.
1413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kIsacCodec);
1417 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001418 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001420 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1423 EXPECT_EQ(96, send_codec_spec.payload_type);
1424 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1425 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1426 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001427 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001428 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429}
1430
ossu20a4b3f2017-04-27 02:08:52 -07001431// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1432// AudioSendStream.
1433TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kIsacCodec);
1437 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001438 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 parameters.codecs[0].id = 96;
1440 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001441 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001443 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001444 // Calling SetSendCodec again with same codec which is already set.
1445 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001448}
1449
ossu20a4b3f2017-04-27 02:08:52 -07001450// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1451// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001452
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001453// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 0;
1459 parameters.codecs[0].clockrate = 50000;
1460 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001463// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 0;
1469 parameters.codecs[0].channels = 0;
1470 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471}
1472
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001473// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].bitrate = 0;
1479 parameters.codecs[0].channels = 0;
1480 parameters.codecs[0].params["stereo"] = "1";
1481 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
1484// Test that if channel is 1 for opus and there's no stereo, we fail.
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].channels = 1;
1491 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001492}
1493
1494// Test that if channel is 1 for opus and stereo=0, we fail.
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001496 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001497 cricket::AudioSendParameters parameters;
1498 parameters.codecs.push_back(kOpusCodec);
1499 parameters.codecs[0].bitrate = 0;
1500 parameters.codecs[0].channels = 1;
1501 parameters.codecs[0].params["stereo"] = "0";
1502 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001503}
1504
1505// Test that if channel is 1 for opus and stereo=1, we fail.
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001507 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001508 cricket::AudioSendParameters parameters;
1509 parameters.codecs.push_back(kOpusCodec);
1510 parameters.codecs[0].bitrate = 0;
1511 parameters.codecs[0].channels = 1;
1512 parameters.codecs[0].params["stereo"] = "1";
1513 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001523 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 0;
1532 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001543 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001546 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001547
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001549 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001550 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001551}
1552
ossu20a4b3f2017-04-27 02:08:52 -07001553// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001555 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kOpusCodec);
1558 parameters.codecs[0].bitrate = 0;
1559 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001561 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
ossu20a4b3f2017-04-27 02:08:52 -07001564// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001570 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001573 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001574
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001577 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001578}
1579
ossu20a4b3f2017-04-27 02:08:52 -07001580// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001587 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1588 EXPECT_EQ(111, spec.payload_type);
1589 EXPECT_EQ(96000, spec.target_bitrate_bps);
1590 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001591 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001592 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
ossu20a4b3f2017-04-27 02:08:52 -07001595// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].bitrate = 30000;
1601 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001603 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
ossu20a4b3f2017-04-27 02:08:52 -07001606// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters parameters;
1610 parameters.codecs.push_back(kOpusCodec);
1611 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001613 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
ossu20a4b3f2017-04-27 02:08:52 -07001616// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kOpusCodec);
1621 parameters.codecs[0].bitrate = 30000;
1622 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001624 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001625}
1626
stefan13f1a0a2016-11-30 07:22:58 -08001627TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1628 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1629 200000);
1630}
1631
1632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1633 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1634}
1635
1636TEST_F(WebRtcVoiceEngineTestFake,
1637 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1638 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1639}
1640
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1642 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1643}
1644
Yves Gerey665174f2018-06-19 15:03:05 +02001645TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001646 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1647 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001648 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001649 // Setting max bitrate should keep previous min bitrate
1650 // Setting max bitrate should not reset start bitrate.
1651 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1652 SetSdpBitrateParameters(
1653 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1654 Field(&BitrateConstraints::start_bitrate_bps, -1),
1655 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001656 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001657}
1658
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001659// Test that we can enable NACK with opus as callee.
1660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 cricket::AudioSendParameters parameters;
1663 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001664 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1665 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001667 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001668 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001669 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001670
Yves Gerey665174f2018-06-19 15:03:05 +02001671 EXPECT_TRUE(
1672 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001673}
1674
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675// Test that we can enable NACK on receive streams.
1676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters parameters;
1680 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001681 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1682 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001684 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001685 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686}
1687
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688// Test that we can disable NACK on receive streams.
1689TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001690 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001691 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 cricket::AudioSendParameters parameters;
1693 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001694 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1695 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs.clear();
1700 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001702 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703}
1704
1705// Test that NACK is enabled on a new receive stream.
1706TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001707 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 cricket::AudioSendParameters parameters;
1709 parameters.codecs.push_back(kIsacCodec);
1710 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001711 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1712 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
solenberg2100c0b2017-03-01 11:29:29 -08001715 EXPECT_TRUE(AddRecvStream(kSsrcY));
1716 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1717 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1718 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719}
1720
stefanba4c0e42016-02-04 04:12:24 -08001721TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001723 cricket::AudioSendParameters send_parameters;
1724 send_parameters.codecs.push_back(kOpusCodec);
1725 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001727
1728 cricket::AudioRecvParameters recv_parameters;
1729 recv_parameters.codecs.push_back(kIsacCodec);
1730 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001731 EXPECT_TRUE(AddRecvStream(kSsrcX));
1732 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001733 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001734 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001735
ossudedfd282016-06-14 07:12:39 -07001736 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001738 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001739 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001740 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001741}
1742
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001743// Test that we can switch back and forth between Opus and ISAC with CN.
1744TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001745 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 cricket::AudioSendParameters opus_parameters;
1748 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001750 {
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(111, spec.payload_type);
1753 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters isac_parameters;
1757 isac_parameters.codecs.push_back(kIsacCodec);
1758 isac_parameters.codecs.push_back(kCn16000Codec);
1759 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001761 {
ossu20a4b3f2017-04-27 02:08:52 -07001762 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1763 EXPECT_EQ(103, spec.payload_type);
1764 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001765 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001768 {
ossu20a4b3f2017-04-27 02:08:52 -07001769 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1770 EXPECT_EQ(111, spec.payload_type);
1771 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001772 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001773}
1774
1775// Test that we handle various ways of specifying bitrate.
1776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001777 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001778 cricket::AudioSendParameters parameters;
1779 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 {
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(103, spec.payload_type);
1784 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1785 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787
Yves Gerey665174f2018-06-19 15:03:05 +02001788 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001790 {
ossu20a4b3f2017-04-27 02:08:52 -07001791 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1792 EXPECT_EQ(103, spec.payload_type);
1793 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1794 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001795 }
Yves Gerey665174f2018-06-19 15:03:05 +02001796 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001798 {
ossu20a4b3f2017-04-27 02:08:52 -07001799 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1800 EXPECT_EQ(103, spec.payload_type);
1801 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1802 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001803 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001804
Yves Gerey665174f2018-06-19 15:03:05 +02001805 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001807 {
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(0, spec.payload_type);
1810 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1811 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001812 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813
Yves Gerey665174f2018-06-19 15:03:05 +02001814 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 {
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(0, spec.payload_type);
1819 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1820 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001821 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001822
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001824 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001826 {
ossu20a4b3f2017-04-27 02:08:52 -07001827 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1828 EXPECT_EQ(111, spec.payload_type);
1829 EXPECT_STREQ("opus", spec.format.name.c_str());
1830 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832}
1833
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001834// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
1838 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001839}
1840
1841// Test that we can set send codecs even with telephone-event codec as the first
1842// one on the list.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001846 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kIsacCodec);
1848 parameters.codecs.push_back(kPcmuCodec);
1849 parameters.codecs[0].id = 98; // DTMF
1850 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001852 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1853 EXPECT_EQ(96, spec.payload_type);
1854 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001855 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001856 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001857}
1858
Harald Alvestranda1f66612018-02-21 11:24:23 +01001859// Test that CanInsertDtmf() is governed by the send flag
1860TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1861 EXPECT_TRUE(SetupSendStream());
1862 cricket::AudioSendParameters parameters;
1863 parameters.codecs.push_back(kTelephoneEventCodec1);
1864 parameters.codecs.push_back(kPcmuCodec);
1865 parameters.codecs[0].id = 98; // DTMF
1866 parameters.codecs[1].id = 96;
1867 SetSendParameters(parameters);
1868 EXPECT_FALSE(channel_->CanInsertDtmf());
1869 SetSend(true);
1870 EXPECT_TRUE(channel_->CanInsertDtmf());
1871 SetSend(false);
1872 EXPECT_FALSE(channel_->CanInsertDtmf());
1873}
1874
solenberg31642aa2016-03-14 08:00:37 -07001875// Test that payload type range is limited for telephone-event codec.
1876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001877 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001878 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001879 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001880 parameters.codecs.push_back(kIsacCodec);
1881 parameters.codecs[0].id = 0; // DTMF
1882 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001884 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001885 EXPECT_TRUE(channel_->CanInsertDtmf());
1886 parameters.codecs[0].id = 128; // DTMF
1887 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1888 EXPECT_FALSE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001890 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001891 EXPECT_TRUE(channel_->CanInsertDtmf());
1892 parameters.codecs[0].id = -1; // DTMF
1893 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1894 EXPECT_FALSE(channel_->CanInsertDtmf());
1895}
1896
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001897// Test that we can set send codecs even with CN codec as the first
1898// one on the list.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kCn16000Codec);
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
1905 parameters.codecs[0].id = 98; // wideband CN
1906 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001907 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001908 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1909 EXPECT_EQ(96, send_codec_spec.payload_type);
1910 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001911 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001912}
1913
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001914// Test that we set VAD and DTMF types correctly as caller.
1915TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001916 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001917 cricket::AudioSendParameters parameters;
1918 parameters.codecs.push_back(kIsacCodec);
1919 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs.push_back(kCn16000Codec);
1922 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001923 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 parameters.codecs[0].id = 96;
1925 parameters.codecs[2].id = 97; // wideband CN
1926 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001927 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001928 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1929 EXPECT_EQ(96, send_codec_spec.payload_type);
1930 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001931 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001932 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001933 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001934 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935}
1936
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001937// Test that we set VAD and DTMF types correctly as callee.
1938TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001939 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 cricket::AudioSendParameters parameters;
1941 parameters.codecs.push_back(kIsacCodec);
1942 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001943 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs.push_back(kCn16000Codec);
1945 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001946 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0].id = 96;
1948 parameters.codecs[2].id = 97; // wideband CN
1949 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001951 EXPECT_TRUE(
1952 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001953
ossu20a4b3f2017-04-27 02:08:52 -07001954 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1955 EXPECT_EQ(96, send_codec_spec.payload_type);
1956 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001957 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001958 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001959 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001960 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001961}
1962
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001963// Test that we only apply VAD if we have a CN codec that matches the
1964// send codec clockrate.
1965TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001966 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs.push_back(kIsacCodec);
1970 parameters.codecs.push_back(kCn16000Codec);
1971 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001973 {
ossu20a4b3f2017-04-27 02:08:52 -07001974 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1975 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001976 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001977 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001978 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001979 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 {
ossu20a4b3f2017-04-27 02:08:52 -07001983 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1984 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001985 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001986 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001987 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001988 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001989 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001990 {
ossu20a4b3f2017-04-27 02:08:52 -07001991 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1992 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001993 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001994 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001995 }
Brave Yao5225dd82015-03-26 07:39:19 +08001996 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001999 {
ossu20a4b3f2017-04-27 02:08:52 -07002000 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2001 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002002 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002003 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002004}
2005
2006// Test that we perform case-insensitive matching of codec names.
2007TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
2010 parameters.codecs.push_back(kIsacCodec);
2011 parameters.codecs.push_back(kPcmuCodec);
2012 parameters.codecs.push_back(kCn16000Codec);
2013 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002014 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002015 parameters.codecs[0].name = "iSaC";
2016 parameters.codecs[0].id = 96;
2017 parameters.codecs[2].id = 97; // wideband CN
2018 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002019 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002020 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2021 EXPECT_EQ(96, send_codec_spec.payload_type);
2022 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002023 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002024 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002025 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002026 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027}
2028
stefanba4c0e42016-02-04 04:12:24 -08002029class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2030 public:
2031 WebRtcVoiceEngineWithSendSideBweTest()
2032 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2033};
2034
2035TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2036 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002037 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2038 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002039 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002040 "uri", &RtpExtension::uri,
2041 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002042}
2043
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002044// Test support for audio level header extension.
2045TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002046 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002047}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002048TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002049 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002051
solenbergd4adce42016-11-17 06:26:52 -08002052// Test support for transport sequence number header extension.
2053TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2054 TestSetSendRtpHeaderExtensions(
2055 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002056}
solenbergd4adce42016-11-17 06:26:52 -08002057TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2058 TestSetRecvRtpHeaderExtensions(
2059 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060}
2061
solenberg1ac56142015-10-13 03:58:19 -07002062// Test that we can create a channel and start sending on it.
2063TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSendParameters(send_parameters_);
2066 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002067 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002068 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002070}
2071
2072// Test that a channel will send if and only if it has a source and is enabled
2073// for sending.
2074TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002075 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002076 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002077 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2080 SetAudioSend(kSsrcX, true, &fake_source_);
2081 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2082 SetAudioSend(kSsrcX, true, nullptr);
2083 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002084}
2085
solenberg94218532016-06-16 10:53:22 -07002086// Test that a channel is muted/unmuted.
2087TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2088 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002089 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2091 SetAudioSend(kSsrcX, true, nullptr);
2092 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2093 SetAudioSend(kSsrcX, false, nullptr);
2094 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002095}
2096
solenberg6d6e7c52016-04-13 09:07:30 -07002097// Test that SetSendParameters() does not alter a stream's send state.
2098TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2099 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002101
2102 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002103 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105
2106 // Changing RTP header extensions will recreate the AudioSendStream.
2107 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002108 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002109 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002110 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002111
2112 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002115
2116 // Changing RTP header extensions will recreate the AudioSendStream.
2117 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002118 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002120}
2121
solenberg1ac56142015-10-13 03:58:19 -07002122// Test that we can create a channel and start playing out on it.
2123TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002124 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002125 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002126 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002127 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002128 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130}
2131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132// Test that we can add and remove send streams.
2133TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2134 SetupForMultiSendStream();
2135
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002137 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138
solenbergc96df772015-10-21 13:01:53 -07002139 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002140 EXPECT_TRUE(
2141 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002142 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002144 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 }
tfarina5237aaf2015-11-10 23:44:30 -08002146 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147
solenbergc96df772015-10-21 13:01:53 -07002148 // Delete the send streams.
2149 for (uint32_t ssrc : kSsrcs4) {
2150 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002151 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002152 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
solenbergc96df772015-10-21 13:01:53 -07002154 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155}
2156
2157// Test SetSendCodecs correctly configure the codecs in all send streams.
2158TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2159 SetupForMultiSendStream();
2160
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002162 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002163 EXPECT_TRUE(
2164 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 }
2166
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs.push_back(kIsacCodec);
2170 parameters.codecs.push_back(kCn16000Codec);
2171 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173
2174 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002175 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002176 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2177 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002178 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2179 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002180 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002181 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002182 }
2183
minyue7a973442016-10-20 03:27:12 -07002184 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002185 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002186 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002188 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2189 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002190 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2191 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002192 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193 }
2194}
2195
2196// Test we can SetSend on all send streams correctly.
2197TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2198 SetupForMultiSendStream();
2199
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002200 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002201 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002202 EXPECT_TRUE(
2203 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002204 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002206 }
2207
2208 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002209 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002210 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002212 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 }
2214
2215 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002216 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002217 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002218 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002219 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 }
2221}
2222
2223// Test we can set the correct statistics on all send streams.
2224TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2225 SetupForMultiSendStream();
2226
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002228 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002229 EXPECT_TRUE(
2230 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231 }
solenberg85a04962015-10-27 03:35:21 -07002232
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002233 // Create a receive stream to check that none of the send streams end up in
2234 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002235 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002236
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002237 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002238 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002239 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002240 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002241
solenberg85a04962015-10-27 03:35:21 -07002242 // Check stats for the added streams.
2243 {
2244 cricket::VoiceMediaInfo info;
2245 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002246
solenberg85a04962015-10-27 03:35:21 -07002247 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002248 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002249 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002250 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002251 }
hbos1acfbd22016-11-17 23:43:29 -08002252 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002253
2254 // We have added one receive stream. We should see empty stats.
2255 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002256 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002257 }
solenberg1ac56142015-10-13 03:58:19 -07002258
solenberg2100c0b2017-03-01 11:29:29 -08002259 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002260 {
2261 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002263 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002264 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002265 EXPECT_EQ(0u, info.receivers.size());
2266 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002267
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002268 // Deliver a new packet - a default receive stream should be created and we
2269 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002270 {
2271 cricket::VoiceMediaInfo info;
2272 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2273 SetAudioReceiveStreamStats();
2274 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002275 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002276 EXPECT_EQ(1u, info.receivers.size());
2277 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002278 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002279 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002280}
2281
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282// Test that we can add and remove receive streams, and do proper send/playout.
2283// We can receive on multiple streams while sending one stream.
2284TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002285 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002286
solenberg1ac56142015-10-13 03:58:19 -07002287 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002288 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002289 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290
solenberg1ac56142015-10-13 03:58:19 -07002291 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002293 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
solenberg1ac56142015-10-13 03:58:19 -07002296 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298
2299 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2301 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2302 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
2304 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002305 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307
2308 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002309 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2311 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312
aleloi84ef6152016-08-04 05:28:21 -07002313 // Restart playout and make sure recv streams are played out.
2314 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2316 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
aleloi84ef6152016-08-04 05:28:21 -07002318 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2320 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321}
2322
wu@webrtc.org97077a32013-10-25 21:18:33 +00002323TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002324 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002325 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002326 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002327 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002328 const auto& agc_config = apm_config_.gain_controller1;
2329
2330 // Ensure default options.
2331 VerifyGainControlEnabledCorrectly();
2332 VerifyGainControlDefaultSettings();
2333
2334 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002335 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002336 EXPECT_FALSE(agc_config.enabled);
2337 send_parameters_.options.auto_gain_control = absl::nullopt;
2338
2339 send_parameters_.options.tx_agc_target_dbov = 5;
2340 SetSendParameters(send_parameters_);
2341 EXPECT_EQ(5, agc_config.target_level_dbfs);
2342 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2343
2344 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(10, agc_config.compression_gain_db);
2347 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2348
2349 send_parameters_.options.tx_agc_limiter = false;
2350 SetSendParameters(send_parameters_);
2351 EXPECT_FALSE(agc_config.enable_limiter);
2352 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2353
2354 SetSendParameters(send_parameters_);
2355 // Expect all options to have been preserved.
2356 EXPECT_FALSE(agc_config.enabled);
2357 EXPECT_EQ(5, agc_config.target_level_dbfs);
2358 EXPECT_EQ(10, agc_config.compression_gain_db);
2359 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002360}
2361
minyue6b825df2016-10-31 04:08:32 -07002362TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2363 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002364 send_parameters_.options.audio_network_adaptor = true;
2365 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002366 SetSendParameters(send_parameters_);
2367 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002368 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002369}
2370
2371TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2372 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002373 send_parameters_.options.audio_network_adaptor = true;
2374 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002375 SetSendParameters(send_parameters_);
2376 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002377 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002378 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002379 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002380 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002381 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002382}
2383
2384TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2385 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002386 send_parameters_.options.audio_network_adaptor = true;
2387 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002388 SetSendParameters(send_parameters_);
2389 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002391 const int initial_num = call_.GetNumCreatedSendStreams();
2392 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002393 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002394 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2395 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002396 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002397 // AudioSendStream not expected to be recreated.
2398 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2399 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002400 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002401}
2402
michaelt6672b262017-01-11 10:17:59 -08002403class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2404 : public WebRtcVoiceEngineTestFake {
2405 public:
2406 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2407 : WebRtcVoiceEngineTestFake(
2408 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2409 "Enabled/") {}
2410};
2411
2412TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2413 EXPECT_TRUE(SetupSendStream());
2414 cricket::AudioSendParameters parameters;
2415 parameters.codecs.push_back(kOpusCodec);
2416 SetSendParameters(parameters);
2417 const int initial_num = call_.GetNumCreatedSendStreams();
2418 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2419
2420 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2421 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002422 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2423 constexpr int kMinOverheadBps =
2424 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002425
2426 constexpr int kOpusMinBitrateBps = 6000;
2427 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002428 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002429 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002430 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002431 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002432
Oskar Sundbom78807582017-11-16 11:09:55 +01002433 parameters.options.audio_network_adaptor = true;
2434 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002435 SetSendParameters(parameters);
2436
ossu11bfc532017-02-16 05:37:06 -08002437 constexpr int kMinOverheadWithAnaBps =
2438 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002439
2440 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002441 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002442
minyuececec102017-03-27 13:04:25 -07002443 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002444 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002445}
2446
minyuececec102017-03-27 13:04:25 -07002447// This test is similar to
2448// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2449// additional field trial.
2450TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2451 SetRtpSendParameterUpdatesMaxBitrate) {
2452 EXPECT_TRUE(SetupSendStream());
2453 cricket::AudioSendParameters send_parameters;
2454 send_parameters.codecs.push_back(kOpusCodec);
2455 SetSendParameters(send_parameters);
2456
2457 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2458 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2459 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2460
2461 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002462 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002463 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002464
2465 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2466#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2467 constexpr int kMinOverhead = 3333;
2468#else
2469 constexpr int kMinOverhead = 6666;
2470#endif
2471 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2472}
2473
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002475// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002477 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002478 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479}
2480
2481TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2482 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002483 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002484 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002485 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002486 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002487 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002488 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002489 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490
solenberg85a04962015-10-27 03:35:21 -07002491 // Check stats for the added streams.
2492 {
2493 cricket::VoiceMediaInfo info;
2494 EXPECT_EQ(true, channel_->GetStats(&info));
2495
2496 // We have added one send stream. We should see the stats we've set.
2497 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002498 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002499 // We have added one receive stream. We should see empty stats.
2500 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002501 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002502 }
solenberg1ac56142015-10-13 03:58:19 -07002503
solenberg566ef242015-11-06 15:34:49 -08002504 // Start sending - this affects some reported stats.
2505 {
2506 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002507 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002508 EXPECT_EQ(true, channel_->GetStats(&info));
2509 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002510 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002511 }
2512
solenberg2100c0b2017-03-01 11:29:29 -08002513 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002514 {
2515 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002516 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002517 EXPECT_EQ(true, channel_->GetStats(&info));
2518 EXPECT_EQ(1u, info.senders.size());
2519 EXPECT_EQ(0u, info.receivers.size());
2520 }
solenberg1ac56142015-10-13 03:58:19 -07002521
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002522 // Deliver a new packet - a default receive stream should be created and we
2523 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002524 {
2525 cricket::VoiceMediaInfo info;
2526 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2527 SetAudioReceiveStreamStats();
2528 EXPECT_EQ(true, channel_->GetStats(&info));
2529 EXPECT_EQ(1u, info.senders.size());
2530 EXPECT_EQ(1u, info.receivers.size());
2531 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002532 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002533 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534}
2535
2536// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002537// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002539 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002540 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2541 EXPECT_TRUE(AddRecvStream(kSsrcY));
2542 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543}
2544
2545// Test that the local SSRC is the same on sending and receiving channels if the
2546// receive channel is created before the send channel.
2547TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002548 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002549 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002550 EXPECT_TRUE(
2551 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002552 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2553 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002554}
2555
2556// Test that we can properly receive packets.
2557TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002558 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002559 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002561
Yves Gerey665174f2018-06-19 15:03:05 +02002562 EXPECT_TRUE(
2563 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564}
2565
2566// Test that we can properly receive packets on multiple streams.
2567TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002568 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002569 const uint32_t ssrc1 = 1;
2570 const uint32_t ssrc2 = 2;
2571 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002572 EXPECT_TRUE(AddRecvStream(ssrc1));
2573 EXPECT_TRUE(AddRecvStream(ssrc2));
2574 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002575 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002576 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002577 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002578 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002579 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002580 }
mflodman3d7db262016-04-29 00:57:13 -07002581
2582 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2583 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2584 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2585
2586 EXPECT_EQ(s1.received_packets(), 0);
2587 EXPECT_EQ(s2.received_packets(), 0);
2588 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002589
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002590 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002591 EXPECT_EQ(s1.received_packets(), 0);
2592 EXPECT_EQ(s2.received_packets(), 0);
2593 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002594
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002595 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002596 EXPECT_EQ(s1.received_packets(), 1);
2597 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2598 EXPECT_EQ(s2.received_packets(), 0);
2599 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002600
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002601 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002602 EXPECT_EQ(s1.received_packets(), 1);
2603 EXPECT_EQ(s2.received_packets(), 1);
2604 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2605 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002606
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002607 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002608 EXPECT_EQ(s1.received_packets(), 1);
2609 EXPECT_EQ(s2.received_packets(), 1);
2610 EXPECT_EQ(s3.received_packets(), 1);
2611 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002612
mflodman3d7db262016-04-29 00:57:13 -07002613 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2614 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2615 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002616}
2617
solenberg2100c0b2017-03-01 11:29:29 -08002618// Test that receiving on an unsignaled stream works (a stream is created).
2619TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002620 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002621 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002622
solenberg7e63ef02015-11-20 00:19:43 -08002623 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002624
Mirko Bonadeif859e552018-05-30 15:31:29 +02002625 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002626 EXPECT_TRUE(
2627 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002628}
2629
Seth Hampson5897a6e2018-04-03 11:16:33 -07002630// Tests that when we add a stream without SSRCs, but contains a stream_id
2631// that it is stored and its stream id is later used when the first packet
2632// arrives to properly create a receive stream with a sync label.
2633TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2634 const char kSyncLabel[] = "sync_label";
2635 EXPECT_TRUE(SetupChannel());
2636 cricket::StreamParams unsignaled_stream;
2637 unsignaled_stream.set_stream_ids({kSyncLabel});
2638 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2639 // The stream shouldn't have been created at this point because it doesn't
2640 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002641 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002642
2643 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2644
Mirko Bonadeif859e552018-05-30 15:31:29 +02002645 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002646 EXPECT_TRUE(
2647 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2648 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2649
2650 // Removing the unsignaled stream clears the cached parameters. If a new
2651 // default unsignaled receive stream is created it will not have a sync group.
2652 channel_->RemoveRecvStream(0);
2653 channel_->RemoveRecvStream(kSsrc1);
2654
2655 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2656
Mirko Bonadeif859e552018-05-30 15:31:29 +02002657 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002658 EXPECT_TRUE(
2659 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2660 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2661}
2662
solenberg2100c0b2017-03-01 11:29:29 -08002663// Test that receiving N unsignaled stream works (streams will be created), and
2664// that packets are forwarded to them all.
2665TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002666 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002667 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002668 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2669
solenberg2100c0b2017-03-01 11:29:29 -08002670 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002671 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002672 rtc::SetBE32(&packet[8], ssrc);
2673 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002674
solenberg2100c0b2017-03-01 11:29:29 -08002675 // Verify we have one new stream for each loop iteration.
2676 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002677 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2678 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002679 }
mflodman3d7db262016-04-29 00:57:13 -07002680
solenberg2100c0b2017-03-01 11:29:29 -08002681 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002682 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002683 rtc::SetBE32(&packet[8], ssrc);
2684 DeliverPacket(packet, sizeof(packet));
2685
solenbergebb349d2017-03-13 05:46:15 -07002686 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002687 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2688 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2689 }
2690
2691 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2692 constexpr uint32_t kAnotherSsrc = 667;
2693 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002694 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002695
2696 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002697 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002698 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002699 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002700 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2701 EXPECT_EQ(2, streams[i]->received_packets());
2702 }
2703 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2704 EXPECT_EQ(1, streams[i]->received_packets());
2705 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002706 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002707}
2708
solenberg2100c0b2017-03-01 11:29:29 -08002709// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002710// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002711TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002712 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002713 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002714 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2715
2716 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002717 const uint32_t signaled_ssrc = 1;
2718 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002719 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002720 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002721 EXPECT_TRUE(
2722 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002723 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002724
2725 // Note that the first unknown SSRC cannot be 0, because we only support
2726 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002727 const uint32_t unsignaled_ssrc = 7011;
2728 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002729 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002730 EXPECT_TRUE(
2731 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002732 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002733
2734 DeliverPacket(packet, sizeof(packet));
2735 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2736
2737 rtc::SetBE32(&packet[8], signaled_ssrc);
2738 DeliverPacket(packet, sizeof(packet));
2739 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002740 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002741}
2742
solenberg4904fb62017-02-17 12:01:14 -08002743// Two tests to verify that adding a receive stream with the same SSRC as a
2744// previously added unsignaled stream will only recreate underlying stream
2745// objects if the stream parameters have changed.
2746TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2747 EXPECT_TRUE(SetupChannel());
2748
2749 // Spawn unsignaled stream with SSRC=1.
2750 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002751 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002752 EXPECT_TRUE(
2753 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002754
2755 // Verify that the underlying stream object in Call is not recreated when a
2756 // stream with SSRC=1 is added.
2757 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002758 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002759 int audio_receive_stream_id = streams.front()->id();
2760 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002761 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002762 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2763}
2764
2765TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2766 EXPECT_TRUE(SetupChannel());
2767
2768 // Spawn unsignaled stream with SSRC=1.
2769 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002770 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002771 EXPECT_TRUE(
2772 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002773
2774 // Verify that the underlying stream object in Call *is* recreated when a
2775 // stream with SSRC=1 is added, and which has changed stream parameters.
2776 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002777 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002778 int audio_receive_stream_id = streams.front()->id();
2779 cricket::StreamParams stream_params;
2780 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002781 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002782 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002783 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002784 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2785}
2786
solenberg1ac56142015-10-13 03:58:19 -07002787// Test that AddRecvStream creates new stream.
2788TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002789 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002790 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
2793// Test that after adding a recv stream, we do not decode more codecs than
2794// those previously passed into SetRecvCodecs.
2795TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002796 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002797 cricket::AudioRecvParameters parameters;
2798 parameters.codecs.push_back(kIsacCodec);
2799 parameters.codecs.push_back(kPcmuCodec);
2800 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002801 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002802 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2803 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2804 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002805}
2806
2807// Test that we properly clean up any streams that were added, even if
2808// not explicitly removed.
2809TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002810 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002811 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002812 EXPECT_TRUE(AddRecvStream(1));
2813 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002814
Mirko Bonadeif859e552018-05-30 15:31:29 +02002815 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2816 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817 delete channel_;
2818 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002819 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2820 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002821}
2822
wu@webrtc.org78187522013-10-07 23:32:02 +00002823TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002824 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002825 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002826}
2827
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002828TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002829 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002830 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002831 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002832}
2833
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002834// Test the InsertDtmf on default send stream as caller.
2835TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002836 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837}
2838
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002839// Test the InsertDtmf on default send stream as callee
2840TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002841 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002842}
2843
2844// Test the InsertDtmf on specified send stream as caller.
2845TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002846 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002847}
2848
2849// Test the InsertDtmf on specified send stream as callee.
2850TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002851 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852}
2853
Johannes Kron9190b822018-10-29 11:22:05 +01002854// Test propagation of extmap allow mixed setting.
2855TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2856 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2857}
2858TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2859 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2860}
2861TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2862 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2863}
2864TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2865 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2866}
2867
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002870 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002871 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2872 .Times(9)
2873 .WillRepeatedly(Return(false));
2874 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2875 .Times(4)
2876 .WillRepeatedly(Return(false));
2877 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2878 .Times(2)
2879 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002880
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002881 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002882 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883
solenberg246b8172015-12-08 09:50:23 -08002884 // Nothing set in AudioOptions, so everything should be as default.
2885 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002886 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002887 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002888 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002889 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002890 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002891 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892
Sam Zackrissonba502232019-01-04 10:36:48 +01002893 // Turn typing detection off.
2894 send_parameters_.options.typing_detection = false;
2895 SetSendParameters(send_parameters_);
2896 EXPECT_FALSE(IsTypingDetectionEnabled());
2897
2898 // Leave typing detection unchanged, but non-default.
2899 send_parameters_.options.typing_detection = absl::nullopt;
2900 SetSendParameters(send_parameters_);
2901 EXPECT_FALSE(IsTypingDetectionEnabled());
2902
2903 // Turn typing detection on.
2904 send_parameters_.options.typing_detection = true;
2905 SetSendParameters(send_parameters_);
2906 EXPECT_TRUE(IsTypingDetectionEnabled());
2907
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002909 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002910 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002911 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912
2913 // Turn echo cancellation back on, with settings, and make sure
2914 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002915 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002916 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002917 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002919 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2920 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002921 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002922 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002923 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002924
2925 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002926 send_parameters_.options.delay_agnostic_aec = false;
2927 send_parameters_.options.extended_filter_aec = false;
2928 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002929 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002930 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002931
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002932 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002933 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002934 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002935 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002936
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002938 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002939 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002940 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002941 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942
2943 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002944 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002945 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002946 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002947 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002948
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002949 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002952 send_parameters_.options.noise_suppression = false;
2953 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002954 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002955 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002956 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002957 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002958 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959
solenberg1ac56142015-10-13 03:58:19 -07002960 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002961 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002962 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002963 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002964 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002965 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002966}
2967
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002969 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002970 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2971 .Times(8)
2972 .WillRepeatedly(Return(false));
2973 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2974 .Times(8)
2975 .WillRepeatedly(Return(false));
2976 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2977 .Times(8)
2978 .WillRepeatedly(Return(false));
2979 EXPECT_CALL(adm_, RecordingIsInitialized())
2980 .Times(2)
2981 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002982 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2983 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002984 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002985
kwiberg686a8ef2016-02-26 03:00:35 -08002986 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002987 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2988 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2989 cricket::AudioOptions(),
2990 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002991 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002992 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2993 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2994 cricket::AudioOptions(),
2995 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996
2997 // Have to add a stream to make SetSend work.
2998 cricket::StreamParams stream1;
2999 stream1.ssrcs.push_back(1);
3000 channel1->AddSendStream(stream1);
3001 cricket::StreamParams stream2;
3002 stream2.ssrcs.push_back(2);
3003 channel2->AddSendStream(stream2);
3004
3005 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003007 parameters_options_all.options.echo_cancellation = true;
3008 parameters_options_all.options.auto_gain_control = true;
3009 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003010 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003011 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003012 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003013 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003014 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003015 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003016 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003017 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003018 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003019 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020
3021 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003022 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003023 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003024 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003025 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003026 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003027 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003028 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003029 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003030 expected_options.echo_cancellation = true;
3031 expected_options.auto_gain_control = true;
3032 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003033 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034
3035 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003036 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003037 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003038 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003039 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003040 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003041 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003042 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003043 expected_options.echo_cancellation = true;
3044 expected_options.auto_gain_control = false;
3045 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003046 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003048 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003049 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003050 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003051 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003052 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003054 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003055 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003056 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003057 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003058 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003059
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003060 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003061 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003062 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003063 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003064 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003065
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003067 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3068 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003069 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3070 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003071 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003072 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003073 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003074 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003075 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003076 expected_options.echo_cancellation = true;
3077 expected_options.auto_gain_control = false;
3078 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003079 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003080}
3081
wu@webrtc.orgde305012013-10-31 15:40:38 +00003082// This test verifies DSCP settings are properly applied on voice media channel.
3083TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003084 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003085 cricket::FakeNetworkInterface network_interface;
3086 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003087 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003088 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003089
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003090 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003091
Sebastian Jansson84848f22018-11-16 10:40:36 +01003092 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3093 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3094 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003095 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003096 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3097 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3098
3099 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003100 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3101 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3102 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003103 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003104 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3105
3106 // Create a send stream to configure
3107 EXPECT_TRUE(
3108 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3109 parameters = channel->GetRtpSendParameters(kSsrcZ);
3110 ASSERT_FALSE(parameters.encodings.empty());
3111
3112 // Various priorities map to various dscp values.
3113 parameters.encodings[0].network_priority = 4.0;
3114 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003115 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003116 parameters.encodings[0].network_priority = 0.5;
3117 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3118 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3119
3120 // A bad priority does not change the dscp value.
3121 parameters.encodings[0].network_priority = 0.0;
3122 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3123 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003124
Tim Haloun6ca98362018-09-17 17:06:08 -07003125 // Packets should also self-identify their dscp in PacketOptions.
3126 const uint8_t kData[10] = {0};
3127 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003128 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003129
nisse51542be2016-02-12 02:27:06 -08003130 // Verify that setting the option to false resets the
3131 // DiffServCodePoint.
3132 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003133 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3134 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3135 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003136 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003137 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3138 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3139
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003140 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003141}
3142
solenberg4bac9c52015-10-09 02:32:53 -07003143TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003144 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003145 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003146 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003147 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003149 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3150 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3151 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003152}
3153
solenberg2100c0b2017-03-01 11:29:29 -08003154TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003155 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003156
3157 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003158 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003159 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3160
3161 // Should remember the volume "2" which will be set on new unsignaled streams,
3162 // and also set the gain to 2 on existing unsignaled streams.
3163 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3164 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3165
3166 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3167 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3168 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3169 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3170 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3171 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3172
3173 // Setting gain with SSRC=0 should affect all unsignaled streams.
3174 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003175 if (kMaxUnsignaledRecvStreams > 1) {
3176 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3177 }
solenberg2100c0b2017-03-01 11:29:29 -08003178 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3179
3180 // Setting gain on an individual stream affects only that.
3181 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003182 if (kMaxUnsignaledRecvStreams > 1) {
3183 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3184 }
solenberg2100c0b2017-03-01 11:29:29 -08003185 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003186}
3187
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003188TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3189 EXPECT_TRUE(SetupChannel());
3190 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3191 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3192
3193 cricket::StreamParams stream;
3194 stream.ssrcs.push_back(kSsrcY);
3195 EXPECT_TRUE(channel_->AddRecvStream(stream));
3196 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3197 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3198 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3199}
3200
3201TEST_F(WebRtcVoiceEngineTestFake,
3202 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3203 // Here base minimum delay is abbreviated to delay in comments for shortness.
3204 EXPECT_TRUE(SetupChannel());
3205
3206 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3207 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3208 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3209 // Check that it doesn't provide default values for unknown ssrc.
3210 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3211
3212 // Check that default value for unsignaled streams is 0.
3213 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3214
3215 // Should remember the delay 100 which will be set on new unsignaled streams,
3216 // and also set the delay to 100 on existing unsignaled streams.
3217 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3218 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3219 // Check that it doesn't provide default values for unknown ssrc.
3220 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3221
3222 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3223 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3224 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3225 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3226 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3227 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3228
3229 // Setting delay with SSRC=0 should affect all unsignaled streams.
3230 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3231 if (kMaxUnsignaledRecvStreams > 1) {
3232 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3233 }
3234 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3235
3236 // Setting delay on an individual stream affects only that.
3237 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3238 if (kMaxUnsignaledRecvStreams > 1) {
3239 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3240 }
3241 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3242 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3243 // Check that it doesn't provide default values for unknown ssrc.
3244 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3245}
3246
Seth Hampson845e8782018-03-02 11:34:10 -08003247TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003248 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003249 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003250
solenbergff976312016-03-30 23:28:51 -07003251 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003252 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003253 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003254 // Creating two channels to make sure that sync label is set properly for both
3255 // the default voice channel and following ones.
3256 EXPECT_TRUE(channel_->AddRecvStream(sp));
3257 sp.ssrcs[0] += 1;
3258 EXPECT_TRUE(channel_->AddRecvStream(sp));
3259
Mirko Bonadeif859e552018-05-30 15:31:29 +02003260 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003261 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003262 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003263 << "SyncGroup should be set based on stream id";
3264 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003265 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003266 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003267}
3268
solenberg3a941542015-11-16 07:34:50 -08003269// TODO(solenberg): Remove, once recv streams are configured through Call.
3270// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003271TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 // Test that setting the header extensions results in the expected state
3273 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003274 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 ssrcs.push_back(223);
3276 ssrcs.push_back(224);
3277
solenbergff976312016-03-30 23:28:51 -07003278 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003279 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003280 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003281 EXPECT_TRUE(
3282 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003283 }
3284
Mirko Bonadeif859e552018-05-30 15:31:29 +02003285 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003286 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003287 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003288 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003289 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003290 }
3291
3292 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003293 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003294 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003295 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003296 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003297 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003298 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003299 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003300 EXPECT_NE(nullptr, s);
3301 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003302 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3303 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003304 for (const auto& s_ext : s_exts) {
3305 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003306 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003307 }
3308 }
3309 }
3310 }
3311
3312 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003313 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003314 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003315 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003316 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003317 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003318 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003319}
3320
3321TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3322 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003323 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003324 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003325 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003326 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3327 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003329 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003330
solenbergff976312016-03-30 23:28:51 -07003331 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003332 cricket::WebRtcVoiceMediaChannel* media_channel =
3333 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003334 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003335 EXPECT_TRUE(media_channel->AddRecvStream(
3336 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3337
Mirko Bonadeif859e552018-05-30 15:31:29 +02003338 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003339 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003340 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003341 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003342 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003344 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003345 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003346}
Minyue2013aec2015-05-13 14:14:42 +02003347
solenberg0a617e22015-10-20 15:49:38 -07003348// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003349// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003350TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003351 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003352 EXPECT_TRUE(AddRecvStream(kSsrcY));
3353 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003354 EXPECT_TRUE(
3355 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003356 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3357 EXPECT_TRUE(AddRecvStream(kSsrcW));
3358 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003359}
3360
solenberg7602aab2016-11-14 11:30:07 -08003361TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3362 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003363 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003364 EXPECT_TRUE(
3365 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003366 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3367 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3368 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003369 EXPECT_TRUE(
3370 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003371 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3372 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003373}
stefan658910c2015-09-03 05:48:32 -07003374
deadbeef884f5852016-01-15 09:20:04 -08003375TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003376 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003377 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3378 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003379
3380 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003381 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3382 EXPECT_TRUE(AddRecvStream(kSsrcX));
3383 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003384
3385 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003386 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3387 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003388
3389 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003390 channel_->SetRawAudioSink(kSsrcX, nullptr);
3391 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003392}
3393
solenberg2100c0b2017-03-01 11:29:29 -08003394TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003395 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003396 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3397 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003398 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3399 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003400
3401 // Should be able to set a default sink even when no stream exists.
3402 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3403
solenberg2100c0b2017-03-01 11:29:29 -08003404 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3405 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003406 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003407 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003408
3409 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003410 channel_->SetRawAudioSink(kSsrc0, nullptr);
3411 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003412
3413 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003414 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3415 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003416
3417 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003418 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003419 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003420 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3421
3422 // Spawn another unsignaled stream - it should be assigned the default sink
3423 // and the previous unsignaled stream should lose it.
3424 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3425 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3426 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3427 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003428 if (kMaxUnsignaledRecvStreams > 1) {
3429 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3430 }
solenberg2100c0b2017-03-01 11:29:29 -08003431 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3432
3433 // Reset the default sink - the second unsignaled stream should lose it.
3434 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003435 if (kMaxUnsignaledRecvStreams > 1) {
3436 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3437 }
solenberg2100c0b2017-03-01 11:29:29 -08003438 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3439
3440 // Try setting the default sink while two streams exists.
3441 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003442 if (kMaxUnsignaledRecvStreams > 1) {
3443 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3444 }
solenberg2100c0b2017-03-01 11:29:29 -08003445 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3446
3447 // Try setting the sink for the first unsignaled stream using its known SSRC.
3448 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003449 if (kMaxUnsignaledRecvStreams > 1) {
3450 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3451 }
solenberg2100c0b2017-03-01 11:29:29 -08003452 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003453 if (kMaxUnsignaledRecvStreams > 1) {
3454 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3455 }
deadbeef884f5852016-01-15 09:20:04 -08003456}
3457
skvlad7a43d252016-03-22 15:32:27 -07003458// Test that, just like the video channel, the voice channel communicates the
3459// network state to the call.
3460TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003461 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003462
3463 EXPECT_EQ(webrtc::kNetworkUp,
3464 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3465 EXPECT_EQ(webrtc::kNetworkUp,
3466 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3467
3468 channel_->OnReadyToSend(false);
3469 EXPECT_EQ(webrtc::kNetworkDown,
3470 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3471 EXPECT_EQ(webrtc::kNetworkUp,
3472 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3473
3474 channel_->OnReadyToSend(true);
3475 EXPECT_EQ(webrtc::kNetworkUp,
3476 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3477 EXPECT_EQ(webrtc::kNetworkUp,
3478 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3479}
3480
aleloi18e0b672016-10-04 02:45:47 -07003481// Test that playout is still started after changing parameters
3482TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3483 SetupRecvStream();
3484 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003485 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003486
3487 // Changing RTP header extensions will recreate the AudioReceiveStream.
3488 cricket::AudioRecvParameters parameters;
3489 parameters.extensions.push_back(
3490 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3491 channel_->SetRecvParameters(parameters);
3492
solenberg2100c0b2017-03-01 11:29:29 -08003493 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003494}
3495
Zhi Huangfa266ef2017-12-13 10:27:46 -08003496// Tests when GetSources is called with non-existing ssrc, it will return an
3497// empty list of RtpSource without crashing.
3498TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3499 // Setup an recv stream with |kSsrcX|.
3500 SetupRecvStream();
3501 cricket::WebRtcVoiceMediaChannel* media_channel =
3502 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3503 // Call GetSources with |kSsrcY| which doesn't exist.
3504 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3505 EXPECT_EQ(0u, sources.size());
3506}
3507
stefan658910c2015-09-03 05:48:32 -07003508// Tests that the library initializes and shuts down properly.
3509TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003510 // If the VoiceEngine wants to gather available codecs early, that's fine but
3511 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003512 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3513 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003514 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003515 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003516 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003517 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003518 task_queue_factory.get(), &adm,
3519 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003520 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003521 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003522 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003523 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003524 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003525 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3526 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3527 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003528 EXPECT_TRUE(channel != nullptr);
3529 delete channel;
solenbergff976312016-03-30 23:28:51 -07003530}
stefan658910c2015-09-03 05:48:32 -07003531
solenbergff976312016-03-30 23:28:51 -07003532// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003533TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003534 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3535 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003536 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003537 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003538 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003539 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003540 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003541 {
peaha9cc40b2017-06-29 08:32:09 -07003542 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003543 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003544 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003545 task_queue_factory.get(), &adm,
3546 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003547 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003548 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003549 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003550 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003551 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003552 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3553 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3554 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003555 EXPECT_TRUE(channel != nullptr);
3556 delete channel;
3557 }
stefan658910c2015-09-03 05:48:32 -07003558}
3559
ossu20a4b3f2017-04-27 02:08:52 -07003560// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3561TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003562 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3563 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003564 // TODO(ossu): Why are the payload types of codecs with non-static payload
3565 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003566 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003567 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003568 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003569 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003570 task_queue_factory.get(), &adm,
3571 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003572 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003573 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003574 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003575 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003576 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003577 (clockrate == 0 || codec.clockrate == clockrate);
3578 };
3579 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003580 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003581 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003582 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003583 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003584 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003585 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003586 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003587 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003588 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003589 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003590 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003591 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3592 // Remove these checks once both send and receive side assigns payload
3593 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003594 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003595 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003596 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003597 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003598 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003599 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003600 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003601 EXPECT_EQ(111, codec.id);
3602 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3603 EXPECT_EQ("10", codec.params.find("minptime")->second);
3604 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3605 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003606 }
3607 }
stefan658910c2015-09-03 05:48:32 -07003608}
3609
3610// Tests that VoE supports at least 32 channels
3611TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003612 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3613 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003614 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003615 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003616 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003617 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003618 task_queue_factory.get(), &adm,
3619 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003620 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003621 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003622 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003623 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003624 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003625
3626 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003627 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003628 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003629 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3630 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3631 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003632 if (!channel)
3633 break;
stefan658910c2015-09-03 05:48:32 -07003634 channels[num_channels++] = channel;
3635 }
3636
Mirko Bonadeif859e552018-05-30 15:31:29 +02003637 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003638 EXPECT_EQ(expected, num_channels);
3639
3640 while (num_channels > 0) {
3641 delete channels[--num_channels];
3642 }
stefan658910c2015-09-03 05:48:32 -07003643}
3644
3645// Test that we set our preferred codecs properly.
3646TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003647 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3648 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003649 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3650 // - Check that our builtin codecs are usable by Channel.
3651 // - The codecs provided by the engine is usable by Channel.
3652 // It does not check that the codecs in the RecvParameters are actually
3653 // what we sent in - though it's probably reasonable to expect so, if
3654 // SetRecvParameters returns true.
3655 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003656 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003657 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003658 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003659 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003660 task_queue_factory.get(), &adm,
3661 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003662 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003663 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003664 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003665 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003666 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003667 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003668 cricket::AudioOptions(),
3669 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003670 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003671 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003672 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003673}
ossu9def8002017-02-09 05:14:32 -08003674
3675TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3676 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003677 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3678 {48000, 2, 16000, 10000, 20000}};
3679 spec1.info.allow_comfort_noise = false;
3680 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003681 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003682 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3683 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003684 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003685 specs.push_back(webrtc::AudioCodecSpec{
3686 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3687 {16000, 1, 13300}});
3688 specs.push_back(
3689 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3690 specs.push_back(
3691 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003692
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003693 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3694 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003695 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3696 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3697 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003698 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003699 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003700 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003701 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003702
peaha9cc40b2017-06-29 08:32:09 -07003703 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003704 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003705 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3706 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003707 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003708 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003709 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003710 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003711
3712 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3713 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003714 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3715 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3716 if (codecs.size() > index)
3717 return codecs[index];
3718 return missing_codec;
3719 };
ossu9def8002017-02-09 05:14:32 -08003720
3721 // Ensure the general codecs are generated first and in order.
3722 for (size_t i = 0; i != specs.size(); ++i) {
3723 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3724 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3725 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3726 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3727 }
3728
3729 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003730 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003731 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3732 for (size_t i = 0; i != codecs.size(); ++i) {
3733 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003734 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003735 codec.clockrate == format.clockrate_hz &&
3736 codec.channels == format.num_channels) {
3737 return rtc::checked_cast<int>(i);
3738 }
3739 }
3740 return -1;
3741 };
ossu9def8002017-02-09 05:14:32 -08003742
3743 // Ensure all supplementary codecs are generated last. Their internal ordering
3744 // is not important.
3745 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3746 const int num_specs = static_cast<int>(specs.size());
3747 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3748 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3749 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3750 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3751 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3752 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3753 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3754}