blob: fd054df153e86de1b6ad148824383943669b964b [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/webrtc_voice_engine.h"
12
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080015
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020016#include "absl/memory/memory.h"
Niels Möller2edab4c2018-10-22 09:48:08 +020017#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/audio_codecs/builtin_audio_decoder_factory.h"
19#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020020#include "api/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010022#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010023#include "api/task_queue/default_task_queue_factory.h"
Niels Möller65f17ca2019-09-12 13:59:36 +020024#include "api/transport/media/media_transport_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "call/call.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/fake_media_engine.h"
27#include "media/base/fake_network_interface.h"
28#include "media/base/fake_rtp.h"
29#include "media/base/media_constants.h"
30#include "media/engine/fake_webrtc_call.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/audio_device/include/mock_audio_device.h"
32#include "modules/audio_processing/include/mock_audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080034#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010035#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "test/field_trial.h"
37#include "test/gtest.h"
38#include "test/mock_audio_decoder_factory.h"
39#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
Elad Alon157540a2019-02-08 23:37:52 +010041using ::testing::_;
42using ::testing::ContainerEq;
43using ::testing::Contains;
44using ::testing::Field;
45using ::testing::Return;
46using ::testing::ReturnPointee;
47using ::testing::SaveArg;
48using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000049
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010051using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020052
solenberg418b7d32017-06-13 00:38:27 -070053constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070054
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
56const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070057const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
59const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070060const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
61const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020062const cricket::AudioCodec kTelephoneEventCodec1(106,
63 "telephone-event",
64 8000,
65 0,
66 1);
67const cricket::AudioCodec kTelephoneEventCodec2(107,
68 "telephone-event",
69 32000,
70 0,
71 1);
solenberg2779bab2016-11-17 04:45:19 -080072
solenberg2100c0b2017-03-01 11:29:29 -080073const uint32_t kSsrc0 = 0;
74const uint32_t kSsrc1 = 1;
75const uint32_t kSsrcX = 0x99;
76const uint32_t kSsrcY = 0x17;
77const uint32_t kSsrcZ = 0x42;
78const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020079const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080
solenberg971cab02016-06-14 10:02:41 -070081constexpr int kRtpHistoryMs = 5000;
82
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010083constexpr webrtc::AudioProcessing::Config::GainController1::Mode
84 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010085#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010086 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010087#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010088 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010089#endif
90
saza0bad15f2019-10-16 11:46:11 +020091constexpr webrtc::AudioProcessing::Config::NoiseSuppression::Level
92 kDefaultNsLevel =
93 webrtc::AudioProcessing::Config::NoiseSuppression::Level::kHigh;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010094
solenberg9a5f032222017-03-15 06:14:12 -070095void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
96 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010097
98 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010099 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100100 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100101 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700102#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200103 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200104 *adm,
105 SetPlayoutDevice(
106 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
107 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200108 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700109#else
110 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
111#endif // #if defined(WEBRTC_WIN)
112 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200113 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700114 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100115#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200116 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200117 *adm,
118 SetRecordingDevice(
119 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
120 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200121 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100122#else
123 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
124#endif // #if defined(WEBRTC_WIN)
125 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200126 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
127 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100128 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700129 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
130 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
131 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100132
133 // Teardown.
134 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
135 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
136 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
137 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200138 EXPECT_CALL(*adm, Release())
139 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100140 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700141}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200142} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143
solenbergff976312016-03-30 23:28:51 -0700144// Tests that our stub library "works".
145TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100146 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
147 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700148 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700149 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700150 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
151 new rtc::RefCountedObject<
152 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700153 webrtc::AudioProcessing::Config apm_config;
154 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
155 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200156 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700157 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700158 {
ossuc54071d2016-08-17 02:45:41 -0700159 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100160 task_queue_factory.get(), &adm,
161 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100162 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700163 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700164 }
solenbergff976312016-03-30 23:28:51 -0700165}
166
deadbeef884f5852016-01-15 09:20:04 -0800167class FakeAudioSink : public webrtc::AudioSinkInterface {
168 public:
169 void OnData(const Data& audio) override {}
170};
171
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800172class FakeAudioSource : public cricket::AudioSource {
173 void SetSink(Sink* sink) override {}
174};
175
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200176class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177 public:
stefanba4c0e42016-02-04 04:12:24 -0800178 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
179
180 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100181 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
182 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700183 StrictMock<webrtc::test::MockAudioProcessing>>()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100184 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700185 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800186 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700187 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800188 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700189 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
190 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200191 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700192 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800193 // Default Options.
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 Zackrisson03fbace2019-10-21 10:09:25 +0200207 VerifyEchoCancellationSettings(/*enabled=*/true);
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100209 EXPECT_TRUE(IsTypingDetectionEnabled());
saza0bad15f2019-10-16 11:46:11 +0200210 EXPECT_TRUE(apm_config_.noise_suppression.enabled);
211 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100212 VerifyGainControlEnabledCorrectly();
213 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
solenberg8189b022016-06-14 12:13:00 -0700215
solenbergff976312016-03-30 23:28:51 -0700216 bool SetupChannel() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200217 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100218 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
219 cricket::AudioOptions(),
220 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200221 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000222 }
solenberg8189b022016-06-14 12:13:00 -0700223
solenbergff976312016-03-30 23:28:51 -0700224 bool SetupRecvStream() {
225 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700226 return false;
227 }
solenberg2100c0b2017-03-01 11:29:29 -0800228 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700229 }
solenberg8189b022016-06-14 12:13:00 -0700230
solenbergff976312016-03-30 23:28:51 -0700231 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200232 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
233 }
234
235 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700236 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000237 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 }
Florent Castellidacec712018-05-24 16:24:21 +0200239 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800240 return false;
241 }
peaha9cc40b2017-06-29 08:32:09 -0700242 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800243 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 }
solenberg8189b022016-06-14 12:13:00 -0700245
246 bool AddRecvStream(uint32_t ssrc) {
247 EXPECT_TRUE(channel_);
248 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
249 }
250
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700252 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700253 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800254 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
255 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700256 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800257 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258 }
solenberg8189b022016-06-14 12:13:00 -0700259
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700261 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700262 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 }
solenberg8189b022016-06-14 12:13:00 -0700264
Yves Gerey665174f2018-06-19 15:03:05 +0200265 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100267 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
268 const auto* send_stream = call_.GetAudioSendStream(ssrc);
269 EXPECT_TRUE(send_stream);
270 return *send_stream;
271 }
272
deadbeef884f5852016-01-15 09:20:04 -0800273 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
274 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
275 EXPECT_TRUE(recv_stream);
276 return *recv_stream;
277 }
278
solenberg3a941542015-11-16 07:34:50 -0800279 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800280 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800281 }
282
solenberg7add0582015-11-20 09:59:34 -0800283 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800284 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800285 }
286
solenberg059fb442016-10-26 05:12:24 -0700287 void SetSend(bool enable) {
288 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700289 if (enable) {
290 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
291 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
292 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200293 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700294 }
solenberg059fb442016-10-26 05:12:24 -0700295 channel_->SetSend(enable);
296 }
297
298 void SetSendParameters(const cricket::AudioSendParameters& params) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200299 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenberg059fb442016-10-26 05:12:24 -0700300 ASSERT_TRUE(channel_);
301 EXPECT_TRUE(channel_->SetSendParameters(params));
302 }
303
Yves Gerey665174f2018-06-19 15:03:05 +0200304 void SetAudioSend(uint32_t ssrc,
305 bool enable,
306 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700307 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700308 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700309 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700310 if (enable && options) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200311 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
minyue6b825df2016-10-31 04:08:32 -0700312 }
313 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700314 }
315
Yves Gerey665174f2018-06-19 15:03:05 +0200316 void TestInsertDtmf(uint32_t ssrc,
317 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800318 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700319 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700321 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200323 EXPECT_TRUE(
324 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000325 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
329 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800332 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700333 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000335
336 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700337 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200339 EXPECT_TRUE(
340 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000341 }
342
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800344 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100346 // Test send.
347 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800348 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800350 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800351 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800352 EXPECT_EQ(codec.id, telephone_event.payload_type);
353 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100354 EXPECT_EQ(2, telephone_event.event_code);
355 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 }
357
Johannes Kron9190b822018-10-29 11:22:05 +0100358 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
359 // For a caller, the answer will be applied in set remote description
360 // where SetSendParameters() is called.
361 EXPECT_TRUE(SetupChannel());
362 EXPECT_TRUE(
363 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
364 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
365 SetSendParameters(send_parameters_);
366 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
367 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
368 }
369
370 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
371 // For a callee, the answer will be applied in set local description
372 // where SetExtmapAllowMixed() and AddSendStream() are called.
373 EXPECT_TRUE(SetupChannel());
374 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
375 EXPECT_TRUE(
376 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
377
378 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
379 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
380 }
381
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 // Test that send bandwidth is set correctly.
383 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000384 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
385 // |expected_result| is the expected result from SetMaxSendBandwidth().
386 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700387 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
388 int max_bitrate,
389 bool expected_result,
390 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200391 cricket::AudioSendParameters parameters;
392 parameters.codecs.push_back(codec);
393 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700394 if (expected_result) {
395 SetSendParameters(parameters);
396 } else {
397 EXPECT_FALSE(channel_->SetSendParameters(parameters));
398 }
solenberg2100c0b2017-03-01 11:29:29 -0800399 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400 }
401
skvlade0d46372016-04-07 22:59:22 -0700402 // Sets the per-stream maximum bitrate limit for the specified SSRC.
403 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700404 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700405 EXPECT_EQ(1UL, parameters.encodings.size());
406
Oskar Sundbom78807582017-11-16 11:09:55 +0100407 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800408 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700409 }
410
solenberg059fb442016-10-26 05:12:24 -0700411 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700412 cricket::AudioSendParameters send_parameters;
413 send_parameters.codecs.push_back(codec);
414 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700415 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700416 }
417
ossu20a4b3f2017-04-27 02:08:52 -0700418 void CheckSendCodecBitrate(int32_t ssrc,
419 const char expected_name[],
420 int expected_bitrate) {
421 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
422 EXPECT_EQ(expected_name, spec->format.name);
423 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700424 }
425
Danil Chapovalov00c71832018-06-15 15:58:38 +0200426 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700427 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700428 }
429
Danil Chapovalov00c71832018-06-15 15:58:38 +0200430 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
431 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700432 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
433 }
434
skvlade0d46372016-04-07 22:59:22 -0700435 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
436 int global_max,
437 int stream_max,
438 bool expected_result,
439 int expected_codec_bitrate) {
440 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800441 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700442
443 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700444 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800445 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700446
447 // Verify that reading back the parameters gives results
448 // consistent with the Set() result.
449 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800450 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700451 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
452 EXPECT_EQ(expected_result ? stream_max : -1,
453 resulting_parameters.encodings[0].max_bitrate_bps);
454
455 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700457 }
458
stefan13f1a0a2016-11-30 07:22:58 -0800459 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
460 int expected_min_bitrate_bps,
461 const char* start_bitrate_kbps,
462 int expected_start_bitrate_bps,
463 const char* max_bitrate_kbps,
464 int expected_max_bitrate_bps) {
465 EXPECT_TRUE(SetupSendStream());
466 auto& codecs = send_parameters_.codecs;
467 codecs.clear();
468 codecs.push_back(kOpusCodec);
469 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
470 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
471 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100472 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
473 SetSdpBitrateParameters(
474 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
475 expected_min_bitrate_bps),
476 Field(&BitrateConstraints::start_bitrate_bps,
477 expected_start_bitrate_bps),
478 Field(&BitrateConstraints::max_bitrate_bps,
479 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800480
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100481 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800482 }
483
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000484 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700485 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000486
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800488 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000489
490 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700491 send_parameters_.extensions.push_back(
492 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000495
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200497 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700498 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extension is set properly.
502 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700503 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700504 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800505 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
506 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
507 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000508
solenberg7add0582015-11-20 09:59:34 -0800509 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200510 EXPECT_TRUE(
511 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800512 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
513 call_.GetAudioSendStream(kSsrcY));
514 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
515 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
516 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000517
518 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200519 send_parameters_.codecs.push_back(kPcmuCodec);
520 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700521 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800522 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
523 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524 }
525
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000526 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700527 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000528
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000529 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800530 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000531
532 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700533 recv_parameters_.extensions.push_back(
534 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800535 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800536 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000537
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000538 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800539 recv_parameters_.extensions.clear();
540 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800541 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000542
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000543 // Ensure extension is set properly.
544 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700545 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800546 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800547 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
548 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
549 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000550
solenberg7add0582015-11-20 09:59:34 -0800551 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800552 EXPECT_TRUE(AddRecvStream(kSsrcY));
553 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
554 call_.GetAudioReceiveStream(kSsrcY));
555 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
556 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
557 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000558
559 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800560 recv_parameters_.extensions.clear();
561 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800562 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
563 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000564 }
565
solenberg85a04962015-10-27 03:35:21 -0700566 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
567 webrtc::AudioSendStream::Stats stats;
568 stats.local_ssrc = 12;
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200569 stats.payload_bytes_sent = 345;
570 stats.header_and_padding_bytes_sent = 56;
solenberg85a04962015-10-27 03:35:21 -0700571 stats.packets_sent = 678;
572 stats.packets_lost = 9012;
573 stats.fraction_lost = 34.56f;
574 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100575 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700576 stats.jitter_ms = 12;
577 stats.rtt_ms = 345;
578 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100579 stats.apm_statistics.delay_median_ms = 234;
580 stats.apm_statistics.delay_standard_deviation_ms = 567;
581 stats.apm_statistics.echo_return_loss = 890;
582 stats.apm_statistics.echo_return_loss_enhancement = 1234;
583 stats.apm_statistics.residual_echo_likelihood = 0.432f;
584 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100585 stats.ana_statistics.bitrate_action_counter = 321;
586 stats.ana_statistics.channel_action_counter = 432;
587 stats.ana_statistics.dtx_action_counter = 543;
588 stats.ana_statistics.fec_action_counter = 654;
589 stats.ana_statistics.frame_length_increase_counter = 765;
590 stats.ana_statistics.frame_length_decrease_counter = 876;
591 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700592 stats.typing_noise_detected = true;
593 return stats;
594 }
595 void SetAudioSendStreamStats() {
596 for (auto* s : call_.GetAudioSendStreams()) {
597 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200598 }
solenberg85a04962015-10-27 03:35:21 -0700599 }
solenberg566ef242015-11-06 15:34:49 -0800600 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
601 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700602 const auto stats = GetAudioSendStreamStats();
603 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200604 EXPECT_EQ(info.payload_bytes_sent, stats.payload_bytes_sent);
605 EXPECT_EQ(info.header_and_padding_bytes_sent,
606 stats.header_and_padding_bytes_sent);
solenberg85a04962015-10-27 03:35:21 -0700607 EXPECT_EQ(info.packets_sent, stats.packets_sent);
608 EXPECT_EQ(info.packets_lost, stats.packets_lost);
609 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
610 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800611 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700612 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
613 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
614 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100615 EXPECT_EQ(info.apm_statistics.delay_median_ms,
616 stats.apm_statistics.delay_median_ms);
617 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
618 stats.apm_statistics.delay_standard_deviation_ms);
619 EXPECT_EQ(info.apm_statistics.echo_return_loss,
620 stats.apm_statistics.echo_return_loss);
621 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
622 stats.apm_statistics.echo_return_loss_enhancement);
623 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
624 stats.apm_statistics.residual_echo_likelihood);
625 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
626 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700627 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
628 stats.ana_statistics.bitrate_action_counter);
629 EXPECT_EQ(info.ana_statistics.channel_action_counter,
630 stats.ana_statistics.channel_action_counter);
631 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
632 stats.ana_statistics.dtx_action_counter);
633 EXPECT_EQ(info.ana_statistics.fec_action_counter,
634 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700635 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
636 stats.ana_statistics.frame_length_increase_counter);
637 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
638 stats.ana_statistics.frame_length_decrease_counter);
639 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
640 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800641 EXPECT_EQ(info.typing_noise_detected,
642 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700643 }
644
645 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
646 webrtc::AudioReceiveStream::Stats stats;
647 stats.remote_ssrc = 123;
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200648 stats.payload_bytes_rcvd = 456;
649 stats.header_and_padding_bytes_rcvd = 67;
solenberg85a04962015-10-27 03:35:21 -0700650 stats.packets_rcvd = 768;
651 stats.packets_lost = 101;
solenberg85a04962015-10-27 03:35:21 -0700652 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100653 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700654 stats.jitter_ms = 901;
655 stats.jitter_buffer_ms = 234;
656 stats.jitter_buffer_preferred_ms = 567;
657 stats.delay_estimate_ms = 890;
658 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700659 stats.total_samples_received = 5678901;
660 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200661 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200662 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100663 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700664 stats.expand_rate = 5.67f;
665 stats.speech_expand_rate = 8.90f;
666 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200667 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700668 stats.accelerate_rate = 4.56f;
669 stats.preemptive_expand_rate = 7.89f;
670 stats.decoding_calls_to_silence_generator = 12;
671 stats.decoding_calls_to_neteq = 345;
672 stats.decoding_normal = 67890;
673 stats.decoding_plc = 1234;
Alex Narest5b5d97c2019-08-07 18:15:08 +0200674 stats.decoding_codec_plc = 1236;
solenberg85a04962015-10-27 03:35:21 -0700675 stats.decoding_cng = 5678;
676 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700677 stats.decoding_muted_output = 3456;
678 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200679 return stats;
680 }
681 void SetAudioReceiveStreamStats() {
682 for (auto* s : call_.GetAudioReceiveStreams()) {
683 s->SetStats(GetAudioReceiveStreamStats());
684 }
685 }
686 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700687 const auto stats = GetAudioReceiveStreamStats();
688 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200689 EXPECT_EQ(info.payload_bytes_rcvd, stats.payload_bytes_rcvd);
690 EXPECT_EQ(info.header_and_padding_bytes_rcvd,
691 stats.header_and_padding_bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
693 stats.packets_rcvd);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
695 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700696 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800697 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
700 stats.jitter_buffer_ms);
701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700702 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200703 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
704 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700705 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700706 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
707 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200708 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200709 EXPECT_EQ(info.jitter_buffer_delay_seconds,
710 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100711 EXPECT_EQ(info.jitter_buffer_emitted_count,
712 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700713 EXPECT_EQ(info.expand_rate, stats.expand_rate);
714 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
715 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200716 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700717 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
718 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200719 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700720 stats.decoding_calls_to_silence_generator);
721 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
722 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
723 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
Alex Narest5b5d97c2019-08-07 18:15:08 +0200724 EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
solenberg85a04962015-10-27 03:35:21 -0700725 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
726 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700727 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700728 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200729 }
hbos1acfbd22016-11-17 23:43:29 -0800730 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
731 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
732 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
733 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
734 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
735 codec.ToCodecParameters());
736 }
737 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
738 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
739 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
740 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
741 codec.ToCodecParameters());
742 }
743 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200744
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100745 void VerifyGainControlEnabledCorrectly() {
746 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
747 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
748 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
749 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
750 }
751
752 void VerifyGainControlDefaultSettings() {
753 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
754 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
755 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
756 }
757
Sam Zackrisson03fbace2019-10-21 10:09:25 +0200758 void VerifyEchoCancellationSettings(bool enabled) {
759 constexpr bool kDefaultUseAecm =
760#if defined(WEBRTC_ANDROID)
761 true;
762#else
763 false;
764#endif
765 EXPECT_EQ(apm_config_.echo_canceller.enabled, enabled);
766 EXPECT_EQ(apm_config_.echo_canceller.mobile_mode, kDefaultUseAecm);
767 EXPECT_FALSE(apm_config_.echo_canceller.use_legacy_aec);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200768 }
769
peah8271d042016-11-22 07:24:52 -0800770 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100771 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800772 }
773
Sam Zackrissonba502232019-01-04 10:36:48 +0100774 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100775 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100776 }
777
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100779 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700780 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700781 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200782 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700783 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700784 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 cricket::AudioSendParameters send_parameters_;
786 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800787 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700788 webrtc::AudioProcessing::Config apm_config_;
789
stefanba4c0e42016-02-04 04:12:24 -0800790 private:
791 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792};
793
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100795TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700796 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000797}
798
solenberg31fec402016-05-06 02:13:12 -0700799// Test that we can add a send stream and that it has the correct defaults.
800TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
801 EXPECT_TRUE(SetupChannel());
802 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800803 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
804 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
805 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700806 EXPECT_EQ("", config.rtp.c_name);
807 EXPECT_EQ(0u, config.rtp.extensions.size());
808 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
809 config.send_transport);
810}
811
812// Test that we can add a receive stream and that it has the correct defaults.
813TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
814 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800815 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700816 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800817 GetRecvStreamConfig(kSsrcX);
818 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700819 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
820 EXPECT_FALSE(config.rtp.transport_cc);
821 EXPECT_EQ(0u, config.rtp.extensions.size());
822 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
823 config.rtcp_send_transport);
824 EXPECT_EQ("", config.sync_group);
825}
826
stefanba4c0e42016-02-04 04:12:24 -0800827TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700828 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800829 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100830 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800831 if (codec.name == "opus") {
832 EXPECT_TRUE(HasTransportCc(codec));
833 opus_found = true;
834 }
835 }
836 EXPECT_TRUE(opus_found);
837}
838
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839// Test that we set our inbound codecs properly, including changing PT.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
844 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800845 parameters.codecs.push_back(kTelephoneEventCodec1);
846 parameters.codecs.push_back(kTelephoneEventCodec2);
847 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200848 parameters.codecs[2].id = 126;
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800850 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700851 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
852 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
853 {{0, {"PCMU", 8000, 1}},
854 {106, {"ISAC", 16000, 1}},
855 {126, {"telephone-event", 8000, 1}},
856 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
859// Test that we fail to set an unknown inbound codec.
860TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700861 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200862 cricket::AudioRecvParameters parameters;
863 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700864 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200865 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866}
867
868// Test that we fail if we have duplicate types in the inbound list.
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
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(kCn16000Codec);
874 parameters.codecs[1].id = kIsacCodec.id;
875 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876}
877
878// Test that we can decode OPUS without stereo parameters.
879TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700880 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 cricket::AudioRecvParameters parameters;
882 parameters.codecs.push_back(kIsacCodec);
883 parameters.codecs.push_back(kPcmuCodec);
884 parameters.codecs.push_back(kOpusCodec);
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800886 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700887 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
888 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
889 {{0, {"PCMU", 8000, 1}},
890 {103, {"ISAC", 16000, 1}},
891 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894// Test that we can decode OPUS with stereo = 0.
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
899 parameters.codecs.push_back(kPcmuCodec);
900 parameters.codecs.push_back(kOpusCodec);
901 parameters.codecs[2].params["stereo"] = "0";
902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800903 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700904 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
905 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
906 {{0, {"PCMU", 8000, 1}},
907 {103, {"ISAC", 16000, 1}},
908 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can decode OPUS with stereo = 1.
912TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kPcmuCodec);
917 parameters.codecs.push_back(kOpusCodec);
918 parameters.codecs[2].params["stereo"] = "1";
919 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800920 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700921 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
922 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
923 {{0, {"PCMU", 8000, 1}},
924 {103, {"ISAC", 16000, 1}},
925 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926}
927
928// Test that changes to recv codecs are applied to all streams.
929TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700930 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 cricket::AudioRecvParameters parameters;
932 parameters.codecs.push_back(kIsacCodec);
933 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800934 parameters.codecs.push_back(kTelephoneEventCodec1);
935 parameters.codecs.push_back(kTelephoneEventCodec2);
936 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200937 parameters.codecs[2].id = 126;
938 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700939 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
940 EXPECT_TRUE(AddRecvStream(ssrc));
941 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
942 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
943 {{0, {"PCMU", 8000, 1}},
944 {106, {"ISAC", 16000, 1}},
945 {126, {"telephone-event", 8000, 1}},
946 {107, {"telephone-event", 32000, 1}}})));
947 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948}
949
950TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952 cricket::AudioRecvParameters parameters;
953 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800954 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
solenberg2100c0b2017-03-01 11:29:29 -0800957 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200958 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800959 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960}
961
962// Test that we can apply the same set of codecs again while playing.
963TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700964 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965 cricket::AudioRecvParameters parameters;
966 parameters.codecs.push_back(kIsacCodec);
967 parameters.codecs.push_back(kCn16000Codec);
968 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700969 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200970 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971
deadbeefcb383672017-04-26 16:28:42 -0700972 // Remapping a payload type to a different codec should fail.
973 parameters.codecs[0] = kOpusCodec;
974 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800976 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977}
978
979// Test that we can add a codec while playing.
980TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200982 cricket::AudioRecvParameters parameters;
983 parameters.codecs.push_back(kIsacCodec);
984 parameters.codecs.push_back(kCn16000Codec);
985 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700986 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200988 parameters.codecs.push_back(kOpusCodec);
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800990 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991}
992
deadbeefcb383672017-04-26 16:28:42 -0700993// Test that we accept adding the same codec with a different payload type.
994// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
995TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
996 EXPECT_TRUE(SetupRecvStream());
997 cricket::AudioRecvParameters parameters;
998 parameters.codecs.push_back(kIsacCodec);
999 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1000
1001 ++parameters.codecs[0].id;
1002 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1003}
1004
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -07001006 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001008 // Test that when autobw is enabled, bitrate is kept as the default
1009 // value. autobw is enabled for the following tests because the target
1010 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011
1012 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001013 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014
1015 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001016 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017
ossu20a4b3f2017-04-27 02:08:52 -07001018 // opus, default bitrate == 32000 in mono.
1019 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020}
1021
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001022TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001023 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001026 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1027 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001028 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001030 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001031 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1032 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1033 // Rates above the max (510000) should be capped.
1034 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035}
1036
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001037TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001038 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001039
1040 // Test that we can only set a maximum bitrate for a fixed-rate codec
1041 // if it's bigger than the fixed rate.
1042
1043 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001044 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1045 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1046 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1047 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1048 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1049 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1050 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001051}
1052
1053TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001054 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001055 const int kDesiredBitrate = 128000;
1056 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001057 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001058 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001059 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001060
Yves Gerey665174f2018-06-19 15:03:05 +02001061 EXPECT_TRUE(
1062 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001063
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001065}
1066
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067// Test that bitrate cannot be set for CBR codecs.
1068// Bitrate is ignored if it is higher than the fixed bitrate.
1069// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001070TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001071 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001072
1073 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001074 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001076
1077 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001078 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001079 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001080
1081 send_parameters_.max_bandwidth_bps = 128;
1082 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001084}
1085
skvlade0d46372016-04-07 22:59:22 -07001086// Test that the per-stream bitrate limit and the global
1087// bitrate limit both apply.
1088TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1089 EXPECT_TRUE(SetupSendStream());
1090
ossu20a4b3f2017-04-27 02:08:52 -07001091 // opus, default bitrate == 32000.
1092 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001093 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1094 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1095 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1096
1097 // CBR codecs allow both maximums to exceed the bitrate.
1098 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1099 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1100 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1101 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1102
1103 // CBR codecs don't allow per stream maximums to be too low.
1104 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1105 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1106}
1107
1108// Test that an attempt to set RtpParameters for a stream that does not exist
1109// fails.
1110TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1111 EXPECT_TRUE(SetupChannel());
1112 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001113 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001114 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001115
1116 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001117 EXPECT_FALSE(
1118 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001119}
1120
1121TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001122 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001123 // This test verifies that setting RtpParameters succeeds only if
1124 // the structure contains exactly one encoding.
1125 // TODO(skvlad): Update this test when we start supporting setting parameters
1126 // for each encoding individually.
1127
1128 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001129 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001130 // Two or more encodings should result in failure.
1131 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001132 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001133 // Zero encodings should also fail.
1134 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001135 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001136}
1137
1138// Changing the SSRC through RtpParameters is not allowed.
1139TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1140 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001141 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001142 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001143 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001144}
1145
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001147// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001148TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1149 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001150 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001151 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001152 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001153 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001154 ASSERT_EQ(1u, parameters.encodings.size());
1155 ASSERT_TRUE(parameters.encodings[0].active);
1156 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001157 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001158 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001159
1160 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001161 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001162 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001163 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001164 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001165 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001166}
1167
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001168// Test that SetRtpSendParameters configures the correct encoding channel for
1169// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001170TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1171 SetupForMultiSendStream();
1172 // Create send streams.
1173 for (uint32_t ssrc : kSsrcs4) {
1174 EXPECT_TRUE(
1175 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1176 }
1177 // Configure one stream to be limited by the stream config, another to be
1178 // limited by the global max, and the third one with no per-stream limit
1179 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001180 SetGlobalMaxBitrate(kOpusCodec, 32000);
1181 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1182 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001183 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1184
ossu20a4b3f2017-04-27 02:08:52 -07001185 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1186 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1187 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001188
1189 // Remove the global cap; the streams should switch to their respective
1190 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001191 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001192 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1193 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1194 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001195}
1196
Tim Haloun648d28a2018-10-18 16:52:22 -07001197// RTCRtpEncodingParameters.network_priority must be one of a few values
1198// derived from the default priority, corresponding to very-low, low, medium,
1199// or high.
1200TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1201 EXPECT_TRUE(SetupSendStream());
1202 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1203 EXPECT_EQ(1UL, parameters.encodings.size());
1204 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1205 parameters.encodings[0].network_priority);
1206
1207 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1208 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1209 for (auto it : good_values) {
1210 parameters.encodings[0].network_priority = it;
1211 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1212 }
1213 for (auto it : bad_values) {
1214 parameters.encodings[0].network_priority = it;
1215 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1216 }
1217}
1218
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001219// Test that GetRtpSendParameters returns the currently configured codecs.
1220TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221 EXPECT_TRUE(SetupSendStream());
1222 cricket::AudioSendParameters parameters;
1223 parameters.codecs.push_back(kIsacCodec);
1224 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001225 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001226
solenberg2100c0b2017-03-01 11:29:29 -08001227 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001228 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001229 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1230 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001231}
1232
Florent Castellidacec712018-05-24 16:24:21 +02001233// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1234TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1235 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1236 params.cname = "rtcpcname";
1237 EXPECT_TRUE(SetupSendStream(params));
1238
1239 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1240 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1241}
1242
Florent Castelliabe301f2018-06-12 18:33:49 +02001243TEST_F(WebRtcVoiceEngineTestFake,
1244 DetectRtpSendParameterHeaderExtensionsChange) {
1245 EXPECT_TRUE(SetupSendStream());
1246
1247 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1248 rtp_parameters.header_extensions.emplace_back();
1249
1250 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1251
1252 webrtc::RTCError result =
1253 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1254 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1255}
1256
deadbeefcb443432016-12-12 11:12:36 -08001257// Test that GetRtpSendParameters returns an SSRC.
1258TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1259 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001260 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001261 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001262 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001263}
1264
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001265// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001266TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001267 EXPECT_TRUE(SetupSendStream());
1268 cricket::AudioSendParameters parameters;
1269 parameters.codecs.push_back(kIsacCodec);
1270 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001271 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001272
solenberg2100c0b2017-03-01 11:29:29 -08001273 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001274
1275 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001276 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001277
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001278 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001279 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1280 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001281}
1282
minyuececec102017-03-27 13:04:25 -07001283// Test that max_bitrate_bps in send stream config gets updated correctly when
1284// SetRtpSendParameters is called.
1285TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1286 webrtc::test::ScopedFieldTrials override_field_trials(
1287 "WebRTC-Audio-SendSideBwe/Enabled/");
1288 EXPECT_TRUE(SetupSendStream());
1289 cricket::AudioSendParameters send_parameters;
1290 send_parameters.codecs.push_back(kOpusCodec);
1291 SetSendParameters(send_parameters);
1292
1293 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1294 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1295 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1296
1297 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001298 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001299 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001300
1301 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1302 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1303}
1304
Seth Hampson24722b32017-12-22 09:36:42 -08001305// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1306// a value <= 0, setting the parameters returns false.
1307TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1308 EXPECT_TRUE(SetupSendStream());
1309 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1310 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1311 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1312 rtp_parameters.encodings[0].bitrate_priority);
1313
1314 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001315 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001316 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001317 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001318}
1319
1320// Test that the bitrate_priority in the send stream config gets updated when
1321// SetRtpSendParameters is set for the VoiceMediaChannel.
1322TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1323 EXPECT_TRUE(SetupSendStream());
1324 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1325
1326 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1327 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1328 rtp_parameters.encodings[0].bitrate_priority);
1329 double new_bitrate_priority = 2.0;
1330 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001331 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001332
1333 // The priority should get set for both the audio channel's rtp parameters
1334 // and the audio send stream's audio config.
1335 EXPECT_EQ(
1336 new_bitrate_priority,
1337 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1338 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1339}
1340
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001341// Test that GetRtpReceiveParameters returns the currently configured codecs.
1342TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1343 EXPECT_TRUE(SetupRecvStream());
1344 cricket::AudioRecvParameters parameters;
1345 parameters.codecs.push_back(kIsacCodec);
1346 parameters.codecs.push_back(kPcmuCodec);
1347 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1348
1349 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001350 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001351 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1352 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1353 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1354}
1355
deadbeefcb443432016-12-12 11:12:36 -08001356// Test that GetRtpReceiveParameters returns an SSRC.
1357TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1358 EXPECT_TRUE(SetupRecvStream());
1359 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001360 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001361 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001362 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001363}
1364
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365// Test that if we set/get parameters multiple times, we get the same results.
1366TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1367 EXPECT_TRUE(SetupRecvStream());
1368 cricket::AudioRecvParameters parameters;
1369 parameters.codecs.push_back(kIsacCodec);
1370 parameters.codecs.push_back(kPcmuCodec);
1371 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1372
1373 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001374 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001375
1376 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001377 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001378
1379 // ... And this shouldn't change the params returned by
1380 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001381 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1382 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001383}
1384
deadbeef3bc15102017-04-20 19:25:07 -07001385// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1386// aren't signaled. It should return an empty "RtpEncodingParameters" when
1387// configured to receive an unsignaled stream and no packets have been received
1388// yet, and start returning the SSRC once a packet has been received.
1389TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1390 ASSERT_TRUE(SetupChannel());
1391 // Call necessary methods to configure receiving a default stream as
1392 // soon as it arrives.
1393 cricket::AudioRecvParameters parameters;
1394 parameters.codecs.push_back(kIsacCodec);
1395 parameters.codecs.push_back(kPcmuCodec);
1396 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1397
1398 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1399 // stream. Should return nothing.
1400 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1401
1402 // Set a sink for an unsignaled stream.
1403 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1404 // Value of "0" means "unsignaled stream".
1405 channel_->SetRawAudioSink(0, std::move(fake_sink));
1406
1407 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1408 // in this method means "unsignaled stream".
1409 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1410 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1411 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1412
1413 // Receive PCMU packet (SSRC=1).
1414 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1415
1416 // The |ssrc| member should still be unset.
1417 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1418 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1419 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1420}
1421
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422// Test that we apply codecs properly.
1423TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kIsacCodec);
1427 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001428 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001430 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1433 EXPECT_EQ(96, send_codec_spec.payload_type);
1434 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1435 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1436 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001437 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001438 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439}
1440
ossu20a4b3f2017-04-27 02:08:52 -07001441// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1442// AudioSendStream.
1443TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001444 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 cricket::AudioSendParameters parameters;
1446 parameters.codecs.push_back(kIsacCodec);
1447 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001448 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 parameters.codecs[0].id = 96;
1450 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001451 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001452 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001453 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001454 // Calling SetSendCodec again with same codec which is already set.
1455 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001456 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001457 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001458}
1459
ossu20a4b3f2017-04-27 02:08:52 -07001460// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1461// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001462
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001463// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
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].clockrate = 50000;
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, SetSendCodecOpusBad0ChannelsNoStereo) {
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 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481}
1482
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001483// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001485 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001486 cricket::AudioSendParameters parameters;
1487 parameters.codecs.push_back(kOpusCodec);
1488 parameters.codecs[0].bitrate = 0;
1489 parameters.codecs[0].channels = 0;
1490 parameters.codecs[0].params["stereo"] = "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 there's no stereo, we fail.
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
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 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001502}
1503
1504// Test that if channel is 1 for opus and stereo=0, we fail.
1505TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001506 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001507 cricket::AudioSendParameters parameters;
1508 parameters.codecs.push_back(kOpusCodec);
1509 parameters.codecs[0].bitrate = 0;
1510 parameters.codecs[0].channels = 1;
1511 parameters.codecs[0].params["stereo"] = "0";
1512 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513}
1514
1515// Test that if channel is 1 for opus and stereo=1, we fail.
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001517 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].bitrate = 0;
1521 parameters.codecs[0].channels = 1;
1522 parameters.codecs[0].params["stereo"] = "1";
1523 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
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;
solenberg059fb442016-10-26 05:12:24 -07001532 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001533 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001534}
1535
ossu20a4b3f2017-04-27 02:08:52 -07001536// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001537TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001538 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001539 cricket::AudioSendParameters parameters;
1540 parameters.codecs.push_back(kOpusCodec);
1541 parameters.codecs[0].bitrate = 0;
1542 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001544 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001545}
1546
ossu20a4b3f2017-04-27 02:08:52 -07001547// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
1552 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001553 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001555 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001556 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001557
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001559 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001560 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001561}
1562
ossu20a4b3f2017-04-27 02:08:52 -07001563// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001565 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].bitrate = 0;
1569 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001570 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001571 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572}
1573
ossu20a4b3f2017-04-27 02:08:52 -07001574// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001575TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001576 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 cricket::AudioSendParameters parameters;
1578 parameters.codecs.push_back(kOpusCodec);
1579 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001580 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001581 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001582 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001583 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001584
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001587 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001588}
1589
ossu20a4b3f2017-04-27 02:08:52 -07001590// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001592 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 cricket::AudioSendParameters parameters;
1594 parameters.codecs.push_back(kOpusCodec);
1595 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001597 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1598 EXPECT_EQ(111, spec.payload_type);
1599 EXPECT_EQ(96000, spec.target_bitrate_bps);
1600 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001601 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001602 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603}
1604
ossu20a4b3f2017-04-27 02:08:52 -07001605// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 cricket::AudioSendParameters parameters;
1609 parameters.codecs.push_back(kOpusCodec);
1610 parameters.codecs[0].bitrate = 30000;
1611 parameters.codecs[0].params["stereo"] = "0";
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 without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
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;
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001623 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624}
1625
ossu20a4b3f2017-04-27 02:08:52 -07001626// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001627TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001628 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 cricket::AudioSendParameters parameters;
1630 parameters.codecs.push_back(kOpusCodec);
1631 parameters.codecs[0].bitrate = 30000;
1632 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001633 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001634 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001635}
1636
stefan13f1a0a2016-11-30 07:22:58 -08001637TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1638 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1639 200000);
1640}
1641
1642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1643 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1644}
1645
1646TEST_F(WebRtcVoiceEngineTestFake,
1647 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1648 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1649}
1650
1651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1652 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1653}
1654
Yves Gerey665174f2018-06-19 15:03:05 +02001655TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001656 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1657 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001658 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001659 // Setting max bitrate should keep previous min bitrate
1660 // Setting max bitrate should not reset start bitrate.
1661 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1662 SetSdpBitrateParameters(
1663 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1664 Field(&BitrateConstraints::start_bitrate_bps, -1),
1665 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001666 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001667}
1668
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001669// Test that we can enable NACK with opus as callee.
1670TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 cricket::AudioSendParameters parameters;
1673 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001674 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1675 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001678 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001679 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001680
Yves Gerey665174f2018-06-19 15:03:05 +02001681 EXPECT_TRUE(
1682 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001683}
1684
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685// Test that we can enable NACK on receive streams.
1686TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001691 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1692 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001695 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696}
1697
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698// Test that we can disable NACK on receive streams.
1699TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001700 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001701 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 cricket::AudioSendParameters parameters;
1703 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001704 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1705 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001706 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001707 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001708
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 parameters.codecs.clear();
1710 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001712 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001713}
1714
1715// Test that NACK is enabled on a new receive stream.
1716TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001717 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 cricket::AudioSendParameters parameters;
1719 parameters.codecs.push_back(kIsacCodec);
1720 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001721 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1722 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724
solenberg2100c0b2017-03-01 11:29:29 -08001725 EXPECT_TRUE(AddRecvStream(kSsrcY));
1726 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1727 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1728 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729}
1730
stefanba4c0e42016-02-04 04:12:24 -08001731TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001732 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001733 cricket::AudioSendParameters send_parameters;
1734 send_parameters.codecs.push_back(kOpusCodec);
1735 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001736 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001737
1738 cricket::AudioRecvParameters recv_parameters;
1739 recv_parameters.codecs.push_back(kIsacCodec);
1740 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001741 EXPECT_TRUE(AddRecvStream(kSsrcX));
1742 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001743 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001744 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001745
ossudedfd282016-06-14 07:12:39 -07001746 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001747 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001748 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001749 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001750 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001751}
1752
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001753// Test that we can switch back and forth between Opus and ISAC with CN.
1754TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001755 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001756
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters opus_parameters;
1758 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001760 {
ossu20a4b3f2017-04-27 02:08:52 -07001761 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1762 EXPECT_EQ(111, spec.payload_type);
1763 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001764 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 cricket::AudioSendParameters isac_parameters;
1767 isac_parameters.codecs.push_back(kIsacCodec);
1768 isac_parameters.codecs.push_back(kCn16000Codec);
1769 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001771 {
ossu20a4b3f2017-04-27 02:08:52 -07001772 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1773 EXPECT_EQ(103, spec.payload_type);
1774 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001775 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001778 {
ossu20a4b3f2017-04-27 02:08:52 -07001779 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1780 EXPECT_EQ(111, spec.payload_type);
1781 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001782 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001783}
1784
1785// Test that we handle various ways of specifying bitrate.
1786TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001787 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001788 cricket::AudioSendParameters parameters;
1789 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001790 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001791 {
ossu20a4b3f2017-04-27 02:08:52 -07001792 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1793 EXPECT_EQ(103, spec.payload_type);
1794 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1795 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001796 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797
Yves Gerey665174f2018-06-19 15:03:05 +02001798 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001799 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001800 {
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(103, spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1804 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001805 }
Yves Gerey665174f2018-06-19 15:03:05 +02001806 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001808 {
ossu20a4b3f2017-04-27 02:08:52 -07001809 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1810 EXPECT_EQ(103, spec.payload_type);
1811 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1812 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001813 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814
Yves Gerey665174f2018-06-19 15:03:05 +02001815 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001817 {
ossu20a4b3f2017-04-27 02:08:52 -07001818 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1819 EXPECT_EQ(0, spec.payload_type);
1820 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1821 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001822 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001823
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(0, spec.payload_type);
1829 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1830 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001834 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001836 {
ossu20a4b3f2017-04-27 02:08:52 -07001837 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1838 EXPECT_EQ(111, spec.payload_type);
1839 EXPECT_STREQ("opus", spec.format.name.c_str());
1840 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001841 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842}
1843
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001844// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001845TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001846 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 cricket::AudioSendParameters parameters;
1848 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001849}
1850
1851// Test that we can set send codecs even with telephone-event codec as the first
1852// one on the list.
1853TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001854 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001855 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001856 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001857 parameters.codecs.push_back(kIsacCodec);
1858 parameters.codecs.push_back(kPcmuCodec);
1859 parameters.codecs[0].id = 98; // DTMF
1860 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001861 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001862 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1863 EXPECT_EQ(96, spec.payload_type);
1864 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001865 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001866 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001867}
1868
Harald Alvestranda1f66612018-02-21 11:24:23 +01001869// Test that CanInsertDtmf() is governed by the send flag
1870TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1871 EXPECT_TRUE(SetupSendStream());
1872 cricket::AudioSendParameters parameters;
1873 parameters.codecs.push_back(kTelephoneEventCodec1);
1874 parameters.codecs.push_back(kPcmuCodec);
1875 parameters.codecs[0].id = 98; // DTMF
1876 parameters.codecs[1].id = 96;
1877 SetSendParameters(parameters);
1878 EXPECT_FALSE(channel_->CanInsertDtmf());
1879 SetSend(true);
1880 EXPECT_TRUE(channel_->CanInsertDtmf());
1881 SetSend(false);
1882 EXPECT_FALSE(channel_->CanInsertDtmf());
1883}
1884
solenberg31642aa2016-03-14 08:00:37 -07001885// Test that payload type range is limited for telephone-event codec.
1886TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001887 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001888 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001889 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001890 parameters.codecs.push_back(kIsacCodec);
1891 parameters.codecs[0].id = 0; // DTMF
1892 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001894 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001895 EXPECT_TRUE(channel_->CanInsertDtmf());
1896 parameters.codecs[0].id = 128; // DTMF
1897 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1898 EXPECT_FALSE(channel_->CanInsertDtmf());
1899 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001901 EXPECT_TRUE(channel_->CanInsertDtmf());
1902 parameters.codecs[0].id = -1; // DTMF
1903 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1904 EXPECT_FALSE(channel_->CanInsertDtmf());
1905}
1906
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001907// Test that we can set send codecs even with CN codec as the first
1908// one on the list.
1909TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001910 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 cricket::AudioSendParameters parameters;
1912 parameters.codecs.push_back(kCn16000Codec);
1913 parameters.codecs.push_back(kIsacCodec);
1914 parameters.codecs.push_back(kPcmuCodec);
1915 parameters.codecs[0].id = 98; // wideband CN
1916 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001917 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001918 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1919 EXPECT_EQ(96, send_codec_spec.payload_type);
1920 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001921 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001922}
1923
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001924// Test that we set VAD and DTMF types correctly as caller.
1925TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001926 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001927 cricket::AudioSendParameters parameters;
1928 parameters.codecs.push_back(kIsacCodec);
1929 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001930 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001931 parameters.codecs.push_back(kCn16000Codec);
1932 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001933 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 parameters.codecs[0].id = 96;
1935 parameters.codecs[2].id = 97; // wideband CN
1936 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001937 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001938 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1939 EXPECT_EQ(96, send_codec_spec.payload_type);
1940 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001941 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001943 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001944 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001945}
1946
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001947// Test that we set VAD and DTMF types correctly as callee.
1948TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001949 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 cricket::AudioSendParameters parameters;
1951 parameters.codecs.push_back(kIsacCodec);
1952 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001953 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001954 parameters.codecs.push_back(kCn16000Codec);
1955 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001956 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 parameters.codecs[0].id = 96;
1958 parameters.codecs[2].id = 97; // wideband CN
1959 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001961 EXPECT_TRUE(
1962 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001963
ossu20a4b3f2017-04-27 02:08:52 -07001964 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1965 EXPECT_EQ(96, send_codec_spec.payload_type);
1966 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001967 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001968 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001969 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001970 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001971}
1972
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001973// Test that we only apply VAD if we have a CN codec that matches the
1974// send codec clockrate.
1975TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001976 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001978 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001979 parameters.codecs.push_back(kIsacCodec);
1980 parameters.codecs.push_back(kCn16000Codec);
1981 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001983 {
ossu20a4b3f2017-04-27 02:08:52 -07001984 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1985 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001986 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001987 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001988 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001989 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001992 {
ossu20a4b3f2017-04-27 02:08:52 -07001993 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1994 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001995 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001996 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001997 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001998 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001999 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002000 {
ossu20a4b3f2017-04-27 02:08:52 -07002001 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2002 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002003 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002004 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002005 }
Brave Yao5225dd82015-03-26 07:39:19 +08002006 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002007 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002008 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002009 {
ossu20a4b3f2017-04-27 02:08:52 -07002010 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2011 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002012 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002013 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002014}
2015
2016// Test that we perform case-insensitive matching of codec names.
2017TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002018 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 cricket::AudioSendParameters parameters;
2020 parameters.codecs.push_back(kIsacCodec);
2021 parameters.codecs.push_back(kPcmuCodec);
2022 parameters.codecs.push_back(kCn16000Codec);
2023 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002024 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002025 parameters.codecs[0].name = "iSaC";
2026 parameters.codecs[0].id = 96;
2027 parameters.codecs[2].id = 97; // wideband CN
2028 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002029 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002030 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2031 EXPECT_EQ(96, send_codec_spec.payload_type);
2032 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002033 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002034 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002035 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002036 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002037}
2038
stefanba4c0e42016-02-04 04:12:24 -08002039class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2040 public:
2041 WebRtcVoiceEngineWithSendSideBweTest()
2042 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2043};
2044
2045TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2046 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002047 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2048 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002049 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002050 "uri", &RtpExtension::uri,
2051 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002052}
2053
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002054// Test support for audio level header extension.
2055TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002056 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002057}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002058TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002059 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002060}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002061
solenbergd4adce42016-11-17 06:26:52 -08002062// Test support for transport sequence number header extension.
2063TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2064 TestSetSendRtpHeaderExtensions(
2065 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002066}
solenbergd4adce42016-11-17 06:26:52 -08002067TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2068 TestSetRecvRtpHeaderExtensions(
2069 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002070}
2071
solenberg1ac56142015-10-13 03:58:19 -07002072// Test that we can create a channel and start sending on it.
2073TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002074 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(send_parameters_);
2076 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002077 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002078 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002080}
2081
2082// Test that a channel will send if and only if it has a source and is enabled
2083// for sending.
2084TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002085 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002086 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002087 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002088 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2090 SetAudioSend(kSsrcX, true, &fake_source_);
2091 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2092 SetAudioSend(kSsrcX, true, nullptr);
2093 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002094}
2095
solenberg94218532016-06-16 10:53:22 -07002096// Test that a channel is muted/unmuted.
2097TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2098 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002099 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2101 SetAudioSend(kSsrcX, true, nullptr);
2102 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2103 SetAudioSend(kSsrcX, false, nullptr);
2104 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002105}
2106
solenberg6d6e7c52016-04-13 09:07:30 -07002107// Test that SetSendParameters() does not alter a stream's send state.
2108TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2109 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002110 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002111
2112 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002115
2116 // Changing RTP header extensions will recreate the AudioSendStream.
2117 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002118 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002120 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002121
2122 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002123 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002124 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002125
2126 // Changing RTP header extensions will recreate the AudioSendStream.
2127 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002128 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002130}
2131
solenberg1ac56142015-10-13 03:58:19 -07002132// Test that we can create a channel and start playing out on it.
2133TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002134 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002135 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002136 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002137 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002138 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002139 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140}
2141
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142// Test that we can add and remove send streams.
2143TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2144 SetupForMultiSendStream();
2145
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002147 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148
solenbergc96df772015-10-21 13:01:53 -07002149 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002150 EXPECT_TRUE(
2151 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002152 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002154 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 }
tfarina5237aaf2015-11-10 23:44:30 -08002156 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157
solenbergc96df772015-10-21 13:01:53 -07002158 // Delete the send streams.
2159 for (uint32_t ssrc : kSsrcs4) {
2160 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002161 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002162 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
solenbergc96df772015-10-21 13:01:53 -07002164 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165}
2166
2167// Test SetSendCodecs correctly configure the codecs in all send streams.
2168TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2169 SetupForMultiSendStream();
2170
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002171 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002172 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002173 EXPECT_TRUE(
2174 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175 }
2176
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002177 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002178 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002179 parameters.codecs.push_back(kIsacCodec);
2180 parameters.codecs.push_back(kCn16000Codec);
2181 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002182 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183
2184 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002185 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002186 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2187 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002188 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2189 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002190 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002191 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002192 }
2193
minyue7a973442016-10-20 03:27:12 -07002194 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002195 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002196 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002197 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002198 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2199 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002200 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2201 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002202 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 }
2204}
2205
2206// Test we can SetSend on all send streams correctly.
2207TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2208 SetupForMultiSendStream();
2209
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002210 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002211 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002212 EXPECT_TRUE(
2213 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002214 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002215 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216 }
2217
2218 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002219 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002220 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002222 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002223 }
2224
2225 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002226 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002227 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002229 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002230 }
2231}
2232
2233// Test we can set the correct statistics on all send streams.
2234TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2235 SetupForMultiSendStream();
2236
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002237 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002238 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002239 EXPECT_TRUE(
2240 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002241 }
solenberg85a04962015-10-27 03:35:21 -07002242
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002243 // Create a receive stream to check that none of the send streams end up in
2244 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002245 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002246
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002247 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002248 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002249 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002250 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002251
solenberg85a04962015-10-27 03:35:21 -07002252 // Check stats for the added streams.
2253 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002254 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002255 cricket::VoiceMediaInfo info;
2256 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002257
solenberg85a04962015-10-27 03:35:21 -07002258 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002259 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002260 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002261 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002262 }
hbos1acfbd22016-11-17 23:43:29 -08002263 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002264
2265 // We have added one receive stream. We should see empty stats.
2266 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002267 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002268 }
solenberg1ac56142015-10-13 03:58:19 -07002269
solenberg2100c0b2017-03-01 11:29:29 -08002270 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002271 {
2272 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002274 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002275 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002276 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002277 EXPECT_EQ(0u, info.receivers.size());
2278 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002279
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002280 // Deliver a new packet - a default receive stream should be created and we
2281 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002282 {
2283 cricket::VoiceMediaInfo info;
2284 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2285 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002286 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002287 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002288 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002289 EXPECT_EQ(1u, info.receivers.size());
2290 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002291 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002292 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002293}
2294
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002295// Test that we can add and remove receive streams, and do proper send/playout.
2296// We can receive on multiple streams while sending one stream.
2297TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002298 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002299
solenberg1ac56142015-10-13 03:58:19 -07002300 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002301 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002302 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
solenberg1ac56142015-10-13 03:58:19 -07002304 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002305 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002306 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002307 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002308
solenberg1ac56142015-10-13 03:58:19 -07002309 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002311
2312 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002313 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2314 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2315 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002316
2317 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002318 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002320
2321 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002322 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002323 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2324 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002325
aleloi84ef6152016-08-04 05:28:21 -07002326 // Restart playout and make sure recv streams are played out.
2327 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002328 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2329 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002330
aleloi84ef6152016-08-04 05:28:21 -07002331 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002332 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2333 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002334}
2335
wu@webrtc.org97077a32013-10-25 21:18:33 +00002336TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002337 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002338 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002339 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002340 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002341 const auto& agc_config = apm_config_.gain_controller1;
2342
2343 // Ensure default options.
2344 VerifyGainControlEnabledCorrectly();
2345 VerifyGainControlDefaultSettings();
2346
2347 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002348 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002349 EXPECT_FALSE(agc_config.enabled);
2350 send_parameters_.options.auto_gain_control = absl::nullopt;
2351
2352 send_parameters_.options.tx_agc_target_dbov = 5;
2353 SetSendParameters(send_parameters_);
2354 EXPECT_EQ(5, agc_config.target_level_dbfs);
2355 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2356
2357 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2358 SetSendParameters(send_parameters_);
2359 EXPECT_EQ(10, agc_config.compression_gain_db);
2360 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2361
2362 send_parameters_.options.tx_agc_limiter = false;
2363 SetSendParameters(send_parameters_);
2364 EXPECT_FALSE(agc_config.enable_limiter);
2365 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2366
2367 SetSendParameters(send_parameters_);
2368 // Expect all options to have been preserved.
2369 EXPECT_FALSE(agc_config.enabled);
2370 EXPECT_EQ(5, agc_config.target_level_dbfs);
2371 EXPECT_EQ(10, agc_config.compression_gain_db);
2372 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002373}
2374
minyue6b825df2016-10-31 04:08:32 -07002375TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2376 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002377 send_parameters_.options.audio_network_adaptor = true;
2378 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002379 SetSendParameters(send_parameters_);
2380 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002381 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002382}
2383
2384TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
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 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002392 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002393 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002394 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002395}
2396
2397TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2398 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002399 send_parameters_.options.audio_network_adaptor = true;
2400 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002401 SetSendParameters(send_parameters_);
2402 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002403 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002404 const int initial_num = call_.GetNumCreatedSendStreams();
2405 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002406 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002407 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2408 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002409 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002410 // AudioSendStream not expected to be recreated.
2411 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2412 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002413 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002414}
2415
michaelt6672b262017-01-11 10:17:59 -08002416class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2417 : public WebRtcVoiceEngineTestFake {
2418 public:
2419 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2420 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002421 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2422 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002423 "Enabled/") {}
2424};
2425
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002426// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002427// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002429 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002430 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431}
2432
2433TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2434 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002435 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002436 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002437 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002438 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002439 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002440 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002441 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002442
solenberg85a04962015-10-27 03:35:21 -07002443 // Check stats for the added streams.
2444 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002445 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002446 cricket::VoiceMediaInfo info;
2447 EXPECT_EQ(true, channel_->GetStats(&info));
2448
2449 // We have added one send stream. We should see the stats we've set.
2450 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002451 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002452 // We have added one receive stream. We should see empty stats.
2453 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002454 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002455 }
solenberg1ac56142015-10-13 03:58:19 -07002456
solenberg566ef242015-11-06 15:34:49 -08002457 // Start sending - this affects some reported stats.
2458 {
2459 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002460 SetSend(true);
Alex Narestbbeb1092019-08-16 11:49:04 +02002461 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg566ef242015-11-06 15:34:49 -08002462 EXPECT_EQ(true, channel_->GetStats(&info));
2463 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002464 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002465 }
2466
solenberg2100c0b2017-03-01 11:29:29 -08002467 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002468 {
2469 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002470 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002471 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002472 EXPECT_EQ(true, channel_->GetStats(&info));
2473 EXPECT_EQ(1u, info.senders.size());
2474 EXPECT_EQ(0u, info.receivers.size());
2475 }
solenberg1ac56142015-10-13 03:58:19 -07002476
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002477 // Deliver a new packet - a default receive stream should be created and we
2478 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002479 {
2480 cricket::VoiceMediaInfo info;
2481 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2482 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002483 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002484 EXPECT_EQ(true, channel_->GetStats(&info));
2485 EXPECT_EQ(1u, info.senders.size());
2486 EXPECT_EQ(1u, info.receivers.size());
2487 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002488 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002489 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490}
2491
2492// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002493// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002495 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002496 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2497 EXPECT_TRUE(AddRecvStream(kSsrcY));
2498 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499}
2500
2501// Test that the local SSRC is the same on sending and receiving channels if the
2502// receive channel is created before the send channel.
2503TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002504 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002505 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002506 EXPECT_TRUE(
2507 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002508 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2509 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510}
2511
2512// Test that we can properly receive packets.
2513TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002514 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002515 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002516 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002517
Yves Gerey665174f2018-06-19 15:03:05 +02002518 EXPECT_TRUE(
2519 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520}
2521
2522// Test that we can properly receive packets on multiple streams.
2523TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002524 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002525 const uint32_t ssrc1 = 1;
2526 const uint32_t ssrc2 = 2;
2527 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002528 EXPECT_TRUE(AddRecvStream(ssrc1));
2529 EXPECT_TRUE(AddRecvStream(ssrc2));
2530 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002532 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002533 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002535 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002536 }
mflodman3d7db262016-04-29 00:57:13 -07002537
2538 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2539 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2540 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2541
2542 EXPECT_EQ(s1.received_packets(), 0);
2543 EXPECT_EQ(s2.received_packets(), 0);
2544 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002545
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002547 EXPECT_EQ(s1.received_packets(), 0);
2548 EXPECT_EQ(s2.received_packets(), 0);
2549 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002550
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002551 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002552 EXPECT_EQ(s1.received_packets(), 1);
2553 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2554 EXPECT_EQ(s2.received_packets(), 0);
2555 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002556
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002558 EXPECT_EQ(s1.received_packets(), 1);
2559 EXPECT_EQ(s2.received_packets(), 1);
2560 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2561 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002562
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002563 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002564 EXPECT_EQ(s1.received_packets(), 1);
2565 EXPECT_EQ(s2.received_packets(), 1);
2566 EXPECT_EQ(s3.received_packets(), 1);
2567 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002568
mflodman3d7db262016-04-29 00:57:13 -07002569 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2570 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2571 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002572}
2573
solenberg2100c0b2017-03-01 11:29:29 -08002574// Test that receiving on an unsignaled stream works (a stream is created).
2575TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002576 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002577 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002578
solenberg7e63ef02015-11-20 00:19:43 -08002579 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002580
Mirko Bonadeif859e552018-05-30 15:31:29 +02002581 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002582 EXPECT_TRUE(
2583 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002584}
2585
Seth Hampson5897a6e2018-04-03 11:16:33 -07002586// Tests that when we add a stream without SSRCs, but contains a stream_id
2587// that it is stored and its stream id is later used when the first packet
2588// arrives to properly create a receive stream with a sync label.
2589TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2590 const char kSyncLabel[] = "sync_label";
2591 EXPECT_TRUE(SetupChannel());
2592 cricket::StreamParams unsignaled_stream;
2593 unsignaled_stream.set_stream_ids({kSyncLabel});
2594 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2595 // The stream shouldn't have been created at this point because it doesn't
2596 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002597 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002598
2599 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2600
Mirko Bonadeif859e552018-05-30 15:31:29 +02002601 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002602 EXPECT_TRUE(
2603 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2604 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2605
Saurav Dasff27da52019-09-20 11:05:30 -07002606 // Remset the unsignaled stream to clear the cached parameters. If a new
Seth Hampson5897a6e2018-04-03 11:16:33 -07002607 // default unsignaled receive stream is created it will not have a sync group.
Saurav Dasff27da52019-09-20 11:05:30 -07002608 channel_->ResetUnsignaledRecvStream();
Seth Hampson5897a6e2018-04-03 11:16:33 -07002609 channel_->RemoveRecvStream(kSsrc1);
2610
2611 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2612
Mirko Bonadeif859e552018-05-30 15:31:29 +02002613 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002614 EXPECT_TRUE(
2615 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2616 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2617}
2618
solenberg2100c0b2017-03-01 11:29:29 -08002619// Test that receiving N unsignaled stream works (streams will be created), and
2620// that packets are forwarded to them all.
2621TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002622 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002623 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002624 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2625
solenberg2100c0b2017-03-01 11:29:29 -08002626 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002627 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002628 rtc::SetBE32(&packet[8], ssrc);
2629 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002630
solenberg2100c0b2017-03-01 11:29:29 -08002631 // Verify we have one new stream for each loop iteration.
2632 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002633 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2634 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002635 }
mflodman3d7db262016-04-29 00:57:13 -07002636
solenberg2100c0b2017-03-01 11:29:29 -08002637 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002638 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002639 rtc::SetBE32(&packet[8], ssrc);
2640 DeliverPacket(packet, sizeof(packet));
2641
solenbergebb349d2017-03-13 05:46:15 -07002642 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002643 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2644 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2645 }
2646
2647 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2648 constexpr uint32_t kAnotherSsrc = 667;
2649 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002650 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002651
2652 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002653 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002654 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002655 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002656 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2657 EXPECT_EQ(2, streams[i]->received_packets());
2658 }
2659 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2660 EXPECT_EQ(1, streams[i]->received_packets());
2661 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002662 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002663}
2664
solenberg2100c0b2017-03-01 11:29:29 -08002665// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002666// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002667TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002668 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002669 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002670 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2671
2672 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002673 const uint32_t signaled_ssrc = 1;
2674 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002675 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002676 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002677 EXPECT_TRUE(
2678 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002679 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002680
2681 // Note that the first unknown SSRC cannot be 0, because we only support
2682 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002683 const uint32_t unsignaled_ssrc = 7011;
2684 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002685 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002686 EXPECT_TRUE(
2687 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002688 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002689
2690 DeliverPacket(packet, sizeof(packet));
2691 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2692
2693 rtc::SetBE32(&packet[8], signaled_ssrc);
2694 DeliverPacket(packet, sizeof(packet));
2695 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002696 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002697}
2698
solenberg4904fb62017-02-17 12:01:14 -08002699// Two tests to verify that adding a receive stream with the same SSRC as a
2700// previously added unsignaled stream will only recreate underlying stream
2701// objects if the stream parameters have changed.
2702TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2703 EXPECT_TRUE(SetupChannel());
2704
2705 // Spawn unsignaled stream with SSRC=1.
2706 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002707 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002708 EXPECT_TRUE(
2709 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002710
2711 // Verify that the underlying stream object in Call is not recreated when a
2712 // stream with SSRC=1 is added.
2713 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002714 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002715 int audio_receive_stream_id = streams.front()->id();
2716 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002717 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002718 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2719}
2720
2721TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2722 EXPECT_TRUE(SetupChannel());
2723
2724 // Spawn unsignaled stream with SSRC=1.
2725 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002726 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002727 EXPECT_TRUE(
2728 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002729
2730 // Verify that the underlying stream object in Call *is* recreated when a
2731 // stream with SSRC=1 is added, and which has changed stream parameters.
2732 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002733 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002734 int audio_receive_stream_id = streams.front()->id();
2735 cricket::StreamParams stream_params;
2736 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002737 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002738 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002739 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002740 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2741}
2742
solenberg1ac56142015-10-13 03:58:19 -07002743// Test that AddRecvStream creates new stream.
2744TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002745 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002746 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747}
2748
2749// Test that after adding a recv stream, we do not decode more codecs than
2750// those previously passed into SetRecvCodecs.
2751TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002752 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002753 cricket::AudioRecvParameters parameters;
2754 parameters.codecs.push_back(kIsacCodec);
2755 parameters.codecs.push_back(kPcmuCodec);
2756 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002757 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002758 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2759 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2760 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761}
2762
2763// Test that we properly clean up any streams that were added, even if
2764// not explicitly removed.
2765TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002766 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002767 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002768 EXPECT_TRUE(AddRecvStream(1));
2769 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002770
Mirko Bonadeif859e552018-05-30 15:31:29 +02002771 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2772 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002773 delete channel_;
2774 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002775 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2776 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002777}
2778
Saurav Dasff27da52019-09-20 11:05:30 -07002779TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamSuccessWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002780 EXPECT_TRUE(SetupSendStream());
Saurav Dasff27da52019-09-20 11:05:30 -07002781 EXPECT_TRUE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002782}
2783
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002784TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002785 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002786 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002787 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002788}
2789
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002790// Test the InsertDtmf on default send stream as caller.
2791TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002792 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793}
2794
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002795// Test the InsertDtmf on default send stream as callee
2796TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002797 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002798}
2799
2800// Test the InsertDtmf on specified send stream as caller.
2801TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002802 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002803}
2804
2805// Test the InsertDtmf on specified send stream as callee.
2806TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002807 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002808}
2809
Johannes Kron9190b822018-10-29 11:22:05 +01002810// Test propagation of extmap allow mixed setting.
2811TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2812 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2813}
2814TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2815 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2816}
2817TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2818 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2819}
2820TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2821 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2822}
2823
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002825 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002826 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002827 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002828 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002829 .WillRepeatedly(Return(false));
2830 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2831 .Times(4)
2832 .WillRepeatedly(Return(false));
2833 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2834 .Times(2)
2835 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002836
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002837 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002838 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002839
solenberg246b8172015-12-08 09:50:23 -08002840 // Nothing set in AudioOptions, so everything should be as default.
2841 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002842 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002843 VerifyEchoCancellationSettings(/*enabled=*/true);
peah8271d042016-11-22 07:24:52 -08002844 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002845 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002846 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002847 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848
Sam Zackrissonba502232019-01-04 10:36:48 +01002849 // Turn typing detection off.
2850 send_parameters_.options.typing_detection = false;
2851 SetSendParameters(send_parameters_);
2852 EXPECT_FALSE(IsTypingDetectionEnabled());
2853
2854 // Leave typing detection unchanged, but non-default.
2855 send_parameters_.options.typing_detection = absl::nullopt;
2856 SetSendParameters(send_parameters_);
2857 EXPECT_FALSE(IsTypingDetectionEnabled());
2858
2859 // Turn typing detection on.
2860 send_parameters_.options.typing_detection = true;
2861 SetSendParameters(send_parameters_);
2862 EXPECT_TRUE(IsTypingDetectionEnabled());
2863
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002866 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002867 VerifyEchoCancellationSettings(/*enabled=*/false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
2869 // Turn echo cancellation back on, with settings, and make sure
2870 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002871 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002872 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002873 VerifyEchoCancellationSettings(/*enabled=*/true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002875 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002876 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002877 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002878 VerifyEchoCancellationSettings(/*enabled=*/false);
solenberg76377c52017-02-21 00:54:31 -08002879
Per Åhgrenf40a3402019-04-25 08:50:11 +02002880 // Restore AEC to be on to work with the following tests.
2881 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002882 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002883
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002885 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002886 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002887 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002888 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
2890 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002891 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002892 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002893 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002894 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002896 // Turn off other options.
Oskar Sundbom78807582017-11-16 11:09:55 +01002897 send_parameters_.options.noise_suppression = false;
2898 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002899 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002900 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002901 VerifyEchoCancellationSettings(/*enabled=*/true);
peah8271d042016-11-22 07:24:52 -08002902 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002903 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
saza0bad15f2019-10-16 11:46:11 +02002904 EXPECT_FALSE(apm_config_.noise_suppression.enabled);
2905 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906
solenberg1ac56142015-10-13 03:58:19 -07002907 // Set options again to ensure it has no impact.
solenberg059fb442016-10-26 05:12:24 -07002908 SetSendParameters(send_parameters_);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002909 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002910 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
saza0bad15f2019-10-16 11:46:11 +02002911 EXPECT_FALSE(apm_config_.noise_suppression.enabled);
2912 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913}
2914
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002916 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002917 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2918 .Times(8)
2919 .WillRepeatedly(Return(false));
2920 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2921 .Times(8)
2922 .WillRepeatedly(Return(false));
2923 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2924 .Times(8)
2925 .WillRepeatedly(Return(false));
2926 EXPECT_CALL(adm_, RecordingIsInitialized())
2927 .Times(2)
2928 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002929 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2930 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002931 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002932
kwiberg686a8ef2016-02-26 03:00:35 -08002933 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002934 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2935 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2936 cricket::AudioOptions(),
2937 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002938 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002939 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2940 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2941 cricket::AudioOptions(),
2942 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002943
2944 // Have to add a stream to make SetSend work.
2945 cricket::StreamParams stream1;
2946 stream1.ssrcs.push_back(1);
2947 channel1->AddSendStream(stream1);
2948 cricket::StreamParams stream2;
2949 stream2.ssrcs.push_back(2);
2950 channel2->AddSendStream(stream2);
2951
2952 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002953 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002954 parameters_options_all.options.echo_cancellation = true;
2955 parameters_options_all.options.auto_gain_control = true;
2956 parameters_options_all.options.noise_suppression = true;
solenberg059fb442016-10-26 05:12:24 -07002957 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002958 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002959 VerifyGainControlEnabledCorrectly();
saza0bad15f2019-10-16 11:46:11 +02002960 EXPECT_TRUE(apm_config_.noise_suppression.enabled);
2961 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002962 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002963 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002964 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002965 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002966 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967
2968 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002969 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002970 parameters_options_no_ns.options.noise_suppression = false;
solenberg059fb442016-10-26 05:12:24 -07002971 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002972 VerifyEchoCancellationSettings(/*enabled=*/true);
saza0bad15f2019-10-16 11:46:11 +02002973 EXPECT_FALSE(apm_config_.noise_suppression.enabled);
2974 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002975 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002976 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002977 expected_options.echo_cancellation = true;
2978 expected_options.auto_gain_control = true;
2979 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002980 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981
2982 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002983 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002984 parameters_options_no_agc.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002985 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002986 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002987 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
saza0bad15f2019-10-16 11:46:11 +02002988 EXPECT_TRUE(apm_config_.noise_suppression.enabled);
2989 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
Oskar Sundbom78807582017-11-16 11:09:55 +01002990 expected_options.echo_cancellation = true;
2991 expected_options.auto_gain_control = false;
2992 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002993 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002994
solenberg059fb442016-10-26 05:12:24 -07002995 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02002996 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002997 VerifyGainControlEnabledCorrectly();
saza0bad15f2019-10-16 11:46:11 +02002998 EXPECT_TRUE(apm_config_.noise_suppression.enabled);
2999 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000
solenberg059fb442016-10-26 05:12:24 -07003001 channel1->SetSend(true);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02003002 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003003 VerifyGainControlEnabledCorrectly();
saza0bad15f2019-10-16 11:46:11 +02003004 EXPECT_FALSE(apm_config_.noise_suppression.enabled);
3005 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006
solenberg059fb442016-10-26 05:12:24 -07003007 channel2->SetSend(true);
Sam Zackrisson03fbace2019-10-21 10:09:25 +02003008 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003009 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
saza0bad15f2019-10-16 11:46:11 +02003010 EXPECT_TRUE(apm_config_.noise_suppression.enabled);
3011 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003013 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003014 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3015 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003016 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3017 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg059fb442016-10-26 05:12:24 -07003018 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson03fbace2019-10-21 10:09:25 +02003019 VerifyEchoCancellationSettings(/*enabled=*/true);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003020 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
saza0bad15f2019-10-16 11:46:11 +02003021 EXPECT_FALSE(apm_config_.noise_suppression.enabled);
3022 EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
Oskar Sundbom78807582017-11-16 11:09:55 +01003023 expected_options.echo_cancellation = true;
3024 expected_options.auto_gain_control = false;
3025 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003026 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027}
3028
wu@webrtc.orgde305012013-10-31 15:40:38 +00003029// This test verifies DSCP settings are properly applied on voice media channel.
3030TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003031 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003032 cricket::FakeNetworkInterface network_interface;
3033 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003034 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003035 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003036
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003037 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003038
Sebastian Jansson84848f22018-11-16 10:40:36 +01003039 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3040 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3041 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003042 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003043 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3044 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3045
3046 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003047 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3048 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3049 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003050 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003051 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3052
3053 // Create a send stream to configure
3054 EXPECT_TRUE(
3055 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3056 parameters = channel->GetRtpSendParameters(kSsrcZ);
3057 ASSERT_FALSE(parameters.encodings.empty());
3058
3059 // Various priorities map to various dscp values.
3060 parameters.encodings[0].network_priority = 4.0;
3061 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003062 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003063 parameters.encodings[0].network_priority = 0.5;
3064 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3065 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3066
3067 // A bad priority does not change the dscp value.
3068 parameters.encodings[0].network_priority = 0.0;
3069 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3070 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003071
Tim Haloun6ca98362018-09-17 17:06:08 -07003072 // Packets should also self-identify their dscp in PacketOptions.
3073 const uint8_t kData[10] = {0};
3074 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003075 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003076
nisse51542be2016-02-12 02:27:06 -08003077 // Verify that setting the option to false resets the
3078 // DiffServCodePoint.
3079 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003080 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3081 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3082 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003083 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003084 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3085 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3086
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003087 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003088}
3089
solenberg4bac9c52015-10-09 02:32:53 -07003090TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003091 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003092 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003093 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003094 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003095 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003096 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3097 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3098 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003099}
3100
solenberg2100c0b2017-03-01 11:29:29 -08003101TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003102 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003103
3104 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003105 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003106 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3107
3108 // Should remember the volume "2" which will be set on new unsignaled streams,
3109 // and also set the gain to 2 on existing unsignaled streams.
3110 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3111 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3112
3113 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3114 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3115 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3116 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3117 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3118 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3119
3120 // Setting gain with SSRC=0 should affect all unsignaled streams.
3121 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003122 if (kMaxUnsignaledRecvStreams > 1) {
3123 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3124 }
solenberg2100c0b2017-03-01 11:29:29 -08003125 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3126
3127 // Setting gain on an individual stream affects only that.
3128 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003129 if (kMaxUnsignaledRecvStreams > 1) {
3130 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3131 }
solenberg2100c0b2017-03-01 11:29:29 -08003132 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003133}
3134
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003135TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3136 EXPECT_TRUE(SetupChannel());
3137 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3138 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3139
3140 cricket::StreamParams stream;
3141 stream.ssrcs.push_back(kSsrcY);
3142 EXPECT_TRUE(channel_->AddRecvStream(stream));
3143 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3144 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3145 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3146}
3147
3148TEST_F(WebRtcVoiceEngineTestFake,
3149 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3150 // Here base minimum delay is abbreviated to delay in comments for shortness.
3151 EXPECT_TRUE(SetupChannel());
3152
3153 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3154 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3155 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3156 // Check that it doesn't provide default values for unknown ssrc.
3157 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3158
3159 // Check that default value for unsignaled streams is 0.
3160 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3161
3162 // Should remember the delay 100 which will be set on new unsignaled streams,
3163 // and also set the delay to 100 on existing unsignaled streams.
3164 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3165 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3166 // Check that it doesn't provide default values for unknown ssrc.
3167 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3168
3169 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3170 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3171 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3172 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3173 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3174 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3175
3176 // Setting delay with SSRC=0 should affect all unsignaled streams.
3177 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3178 if (kMaxUnsignaledRecvStreams > 1) {
3179 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3180 }
3181 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3182
3183 // Setting delay on an individual stream affects only that.
3184 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3185 if (kMaxUnsignaledRecvStreams > 1) {
3186 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3187 }
3188 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3189 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3190 // Check that it doesn't provide default values for unknown ssrc.
3191 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3192}
3193
Seth Hampson845e8782018-03-02 11:34:10 -08003194TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003195 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003196 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003197
solenbergff976312016-03-30 23:28:51 -07003198 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003199 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003200 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003201 // Creating two channels to make sure that sync label is set properly for both
3202 // the default voice channel and following ones.
3203 EXPECT_TRUE(channel_->AddRecvStream(sp));
3204 sp.ssrcs[0] += 1;
3205 EXPECT_TRUE(channel_->AddRecvStream(sp));
3206
Mirko Bonadeif859e552018-05-30 15:31:29 +02003207 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003208 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003209 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003210 << "SyncGroup should be set based on stream id";
3211 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003212 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003213 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003214}
3215
solenberg3a941542015-11-16 07:34:50 -08003216// TODO(solenberg): Remove, once recv streams are configured through Call.
3217// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003218TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003219 // Test that setting the header extensions results in the expected state
3220 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003221 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 ssrcs.push_back(223);
3223 ssrcs.push_back(224);
3224
solenbergff976312016-03-30 23:28:51 -07003225 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003226 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003227 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003228 EXPECT_TRUE(
3229 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003230 }
3231
Mirko Bonadeif859e552018-05-30 15:31:29 +02003232 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003233 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003234 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003235 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003236 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003237 }
3238
3239 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003240 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003241 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003242 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003243 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003244 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003245 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003246 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003247 EXPECT_NE(nullptr, s);
3248 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003249 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3250 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003251 for (const auto& s_ext : s_exts) {
3252 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003253 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003254 }
3255 }
3256 }
3257 }
3258
3259 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003260 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003261 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003262 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003263 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003264 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003265 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003266}
3267
3268TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3269 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003270 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003271 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003273 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3274 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003276 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003277
solenbergff976312016-03-30 23:28:51 -07003278 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003279 cricket::WebRtcVoiceMediaChannel* media_channel =
3280 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003281 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003282 EXPECT_TRUE(media_channel->AddRecvStream(
3283 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3284
Mirko Bonadeif859e552018-05-30 15:31:29 +02003285 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003286 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003287 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003288 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003289 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003290 EXPECT_EQ(1, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003291}
Minyue2013aec2015-05-13 14:14:42 +02003292
solenberg0a617e22015-10-20 15:49:38 -07003293// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003294// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003295TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003296 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003297 EXPECT_TRUE(AddRecvStream(kSsrcY));
3298 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003299 EXPECT_TRUE(
3300 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003301 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3302 EXPECT_TRUE(AddRecvStream(kSsrcW));
3303 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003304}
3305
solenberg7602aab2016-11-14 11:30:07 -08003306TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3307 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003308 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003309 EXPECT_TRUE(
3310 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3312 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3313 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003314 EXPECT_TRUE(
3315 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003316 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3317 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003318}
stefan658910c2015-09-03 05:48:32 -07003319
deadbeef884f5852016-01-15 09:20:04 -08003320TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003321 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003322 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3323 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003324
3325 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003326 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3327 EXPECT_TRUE(AddRecvStream(kSsrcX));
3328 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003329
3330 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003331 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3332 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003333
3334 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003335 channel_->SetRawAudioSink(kSsrcX, nullptr);
3336 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003337}
3338
solenberg2100c0b2017-03-01 11:29:29 -08003339TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003340 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003341 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3342 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003343 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3344 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003345
3346 // Should be able to set a default sink even when no stream exists.
3347 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3348
solenberg2100c0b2017-03-01 11:29:29 -08003349 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3350 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003351 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003352 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003353
3354 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003355 channel_->SetRawAudioSink(kSsrc0, nullptr);
3356 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003357
3358 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003359 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3360 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003361
3362 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003363 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003364 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003365 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3366
3367 // Spawn another unsignaled stream - it should be assigned the default sink
3368 // and the previous unsignaled stream should lose it.
3369 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3370 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3371 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3372 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003373 if (kMaxUnsignaledRecvStreams > 1) {
3374 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3375 }
solenberg2100c0b2017-03-01 11:29:29 -08003376 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3377
3378 // Reset the default sink - the second unsignaled stream should lose it.
3379 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003380 if (kMaxUnsignaledRecvStreams > 1) {
3381 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3382 }
solenberg2100c0b2017-03-01 11:29:29 -08003383 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3384
3385 // Try setting the default sink while two streams exists.
3386 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003387 if (kMaxUnsignaledRecvStreams > 1) {
3388 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3389 }
solenberg2100c0b2017-03-01 11:29:29 -08003390 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3391
3392 // Try setting the sink for the first unsignaled stream using its known SSRC.
3393 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003394 if (kMaxUnsignaledRecvStreams > 1) {
3395 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3396 }
solenberg2100c0b2017-03-01 11:29:29 -08003397 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003398 if (kMaxUnsignaledRecvStreams > 1) {
3399 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3400 }
deadbeef884f5852016-01-15 09:20:04 -08003401}
3402
skvlad7a43d252016-03-22 15:32:27 -07003403// Test that, just like the video channel, the voice channel communicates the
3404// network state to the call.
3405TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003406 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003407
3408 EXPECT_EQ(webrtc::kNetworkUp,
3409 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3410 EXPECT_EQ(webrtc::kNetworkUp,
3411 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3412
3413 channel_->OnReadyToSend(false);
3414 EXPECT_EQ(webrtc::kNetworkDown,
3415 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3416 EXPECT_EQ(webrtc::kNetworkUp,
3417 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3418
3419 channel_->OnReadyToSend(true);
3420 EXPECT_EQ(webrtc::kNetworkUp,
3421 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3422 EXPECT_EQ(webrtc::kNetworkUp,
3423 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3424}
3425
aleloi18e0b672016-10-04 02:45:47 -07003426// Test that playout is still started after changing parameters
3427TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3428 SetupRecvStream();
3429 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003430 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003431
3432 // Changing RTP header extensions will recreate the AudioReceiveStream.
3433 cricket::AudioRecvParameters parameters;
3434 parameters.extensions.push_back(
3435 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3436 channel_->SetRecvParameters(parameters);
3437
solenberg2100c0b2017-03-01 11:29:29 -08003438 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003439}
3440
Zhi Huangfa266ef2017-12-13 10:27:46 -08003441// Tests when GetSources is called with non-existing ssrc, it will return an
3442// empty list of RtpSource without crashing.
3443TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3444 // Setup an recv stream with |kSsrcX|.
3445 SetupRecvStream();
3446 cricket::WebRtcVoiceMediaChannel* media_channel =
3447 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3448 // Call GetSources with |kSsrcY| which doesn't exist.
3449 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3450 EXPECT_EQ(0u, sources.size());
3451}
3452
stefan658910c2015-09-03 05:48:32 -07003453// Tests that the library initializes and shuts down properly.
3454TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003455 // If the VoiceEngine wants to gather available codecs early, that's fine but
3456 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003457 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3458 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003459 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003460 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003461 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003462 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003463 task_queue_factory.get(), &adm,
3464 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003465 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003466 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003467 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003468 webrtc::Call::Config call_config(&event_log);
3469 call_config.task_queue_factory = task_queue_factory.get();
3470 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003471 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3472 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3473 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003474 EXPECT_TRUE(channel != nullptr);
3475 delete channel;
solenbergff976312016-03-30 23:28:51 -07003476}
stefan658910c2015-09-03 05:48:32 -07003477
solenbergff976312016-03-30 23:28:51 -07003478// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003479TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003480 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3481 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003482 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003483 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003484 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003485 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003486 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003487 {
peaha9cc40b2017-06-29 08:32:09 -07003488 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003489 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003490 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003491 task_queue_factory.get(), &adm,
3492 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003493 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003494 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003495 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003496 webrtc::Call::Config call_config(&event_log);
3497 call_config.task_queue_factory = task_queue_factory.get();
3498 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003499 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3500 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3501 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003502 EXPECT_TRUE(channel != nullptr);
3503 delete channel;
3504 }
stefan658910c2015-09-03 05:48:32 -07003505}
3506
ossu20a4b3f2017-04-27 02:08:52 -07003507// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3508TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003509 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3510 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003511 // TODO(ossu): Why are the payload types of codecs with non-static payload
3512 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003513 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003514 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003515 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003516 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003517 task_queue_factory.get(), &adm,
3518 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003519 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003520 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003521 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003522 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003523 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003524 (clockrate == 0 || codec.clockrate == clockrate);
3525 };
3526 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003527 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003528 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003529 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003530 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003531 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003532 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003533 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003534 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003535 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003536 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003537 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003538 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3539 // Remove these checks once both send and receive side assigns payload
3540 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003541 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003542 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003543 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003544 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003545 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003546 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003547 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003548 EXPECT_EQ(111, codec.id);
3549 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3550 EXPECT_EQ("10", codec.params.find("minptime")->second);
3551 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3552 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003553 }
3554 }
stefan658910c2015-09-03 05:48:32 -07003555}
3556
3557// Tests that VoE supports at least 32 channels
3558TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003559 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3560 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003561 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003562 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003563 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003564 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003565 task_queue_factory.get(), &adm,
3566 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003567 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003568 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003569 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003570 webrtc::Call::Config call_config(&event_log);
3571 call_config.task_queue_factory = task_queue_factory.get();
3572 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
stefan658910c2015-09-03 05:48:32 -07003573
3574 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003575 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003576 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003577 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3578 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3579 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003580 if (!channel)
3581 break;
stefan658910c2015-09-03 05:48:32 -07003582 channels[num_channels++] = channel;
3583 }
3584
Mirko Bonadeif859e552018-05-30 15:31:29 +02003585 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003586 EXPECT_EQ(expected, num_channels);
3587
3588 while (num_channels > 0) {
3589 delete channels[--num_channels];
3590 }
stefan658910c2015-09-03 05:48:32 -07003591}
3592
3593// Test that we set our preferred codecs properly.
3594TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003595 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3596 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003597 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3598 // - Check that our builtin codecs are usable by Channel.
3599 // - The codecs provided by the engine is usable by Channel.
3600 // It does not check that the codecs in the RecvParameters are actually
3601 // what we sent in - though it's probably reasonable to expect so, if
3602 // SetRecvParameters returns true.
3603 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003604 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003605 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003606 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003607 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003608 task_queue_factory.get(), &adm,
3609 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003610 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003611 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003612 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003613 webrtc::Call::Config call_config(&event_log);
3614 call_config.task_queue_factory = task_queue_factory.get();
3615 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
nisse51542be2016-02-12 02:27:06 -08003616 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003617 cricket::AudioOptions(),
3618 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003619 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003620 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003621 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003622}
ossu9def8002017-02-09 05:14:32 -08003623
3624TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3625 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003626 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3627 {48000, 2, 16000, 10000, 20000}};
3628 spec1.info.allow_comfort_noise = false;
3629 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003630 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003631 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3632 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003633 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003634 specs.push_back(webrtc::AudioCodecSpec{
3635 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3636 {16000, 1, 13300}});
3637 specs.push_back(
3638 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3639 specs.push_back(
3640 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003641
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003642 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3643 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003644 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3645 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3646 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003647 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003648 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003649 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003650 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003651
peaha9cc40b2017-06-29 08:32:09 -07003652 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003653 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003654 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3655 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003656 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003657 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003658 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003659 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003660
3661 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3662 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003663 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3664 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3665 if (codecs.size() > index)
3666 return codecs[index];
3667 return missing_codec;
3668 };
ossu9def8002017-02-09 05:14:32 -08003669
3670 // Ensure the general codecs are generated first and in order.
3671 for (size_t i = 0; i != specs.size(); ++i) {
3672 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3673 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3674 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3675 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3676 }
3677
3678 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003679 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003680 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3681 for (size_t i = 0; i != codecs.size(); ++i) {
3682 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003683 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003684 codec.clockrate == format.clockrate_hz &&
3685 codec.channels == format.num_channels) {
3686 return rtc::checked_cast<int>(i);
3687 }
3688 }
3689 return -1;
3690 };
ossu9def8002017-02-09 05:14:32 -08003691
3692 // Ensure all supplementary codecs are generated last. Their internal ordering
3693 // is not important.
3694 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3695 const int num_specs = static_cast<int>(specs.size());
3696 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3697 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3698 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3699 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3700 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3701 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3702 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3703}