blob: 3eec446b65d70766842c637b6bd2381314e26d97 [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"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070020#include "api/media_transport_config.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020021#include "api/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010023#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010024#include "api/task_queue/default_task_queue_factory.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
91constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
92 webrtc::NoiseSuppression::kHigh;
93
solenberg9a5f032222017-03-15 06:14:12 -070094void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
95 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010096
97 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010098 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010099 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100100 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700101#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200102 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200103 *adm,
104 SetPlayoutDevice(
105 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
106 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200107 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700108#else
109 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
110#endif // #if defined(WEBRTC_WIN)
111 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200112 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700113 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200115 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200116 *adm,
117 SetRecordingDevice(
118 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
119 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200120 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100121#else
122 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
123#endif // #if defined(WEBRTC_WIN)
124 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200125 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
126 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100127 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700128 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
129 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
130 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100131
132 // Teardown.
133 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
134 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
135 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
136 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200137 EXPECT_CALL(*adm, Release())
138 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100139 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700140}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200141} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142
solenbergff976312016-03-30 23:28:51 -0700143// Tests that our stub library "works".
144TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100145 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
146 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700147 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700148 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700149 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
150 new rtc::RefCountedObject<
151 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700152 webrtc::AudioProcessing::Config apm_config;
153 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
154 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200155 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700156 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700157 {
ossuc54071d2016-08-17 02:45:41 -0700158 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100159 task_queue_factory.get(), &adm,
160 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100161 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700162 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700163 }
solenbergff976312016-03-30 23:28:51 -0700164}
165
deadbeef884f5852016-01-15 09:20:04 -0800166class FakeAudioSink : public webrtc::AudioSinkInterface {
167 public:
168 void OnData(const Data& audio) override {}
169};
170
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800171class FakeAudioSource : public cricket::AudioSource {
172 void SetSink(Sink* sink) override {}
173};
174
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200175class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 public:
stefanba4c0e42016-02-04 04:12:24 -0800177 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
178
179 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100180 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
181 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700182 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700183 apm_ns_(*apm_->noise_suppression()),
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.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100194 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800195 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700196 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800197 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700198 // factories. Those tests should probably be moved elsewhere.
199 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
200 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100201 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100202 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
203 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700204 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200205 send_parameters_.codecs.push_back(kPcmuCodec);
206 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100207
solenberg76377c52017-02-21 00:54:31 -0800208 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200209 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800210 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100211 EXPECT_TRUE(IsTypingDetectionEnabled());
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;
569 stats.bytes_sent = 345;
570 stats.packets_sent = 678;
571 stats.packets_lost = 9012;
572 stats.fraction_lost = 34.56f;
573 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100574 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700575 stats.ext_seqnum = 789;
576 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);
604 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
605 EXPECT_EQ(info.packets_sent, stats.packets_sent);
606 EXPECT_EQ(info.packets_lost, stats.packets_lost);
607 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
608 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800609 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700610 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
611 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
612 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
613 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100614 EXPECT_EQ(info.apm_statistics.delay_median_ms,
615 stats.apm_statistics.delay_median_ms);
616 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
617 stats.apm_statistics.delay_standard_deviation_ms);
618 EXPECT_EQ(info.apm_statistics.echo_return_loss,
619 stats.apm_statistics.echo_return_loss);
620 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
621 stats.apm_statistics.echo_return_loss_enhancement);
622 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
623 stats.apm_statistics.residual_echo_likelihood);
624 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
625 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700626 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
627 stats.ana_statistics.bitrate_action_counter);
628 EXPECT_EQ(info.ana_statistics.channel_action_counter,
629 stats.ana_statistics.channel_action_counter);
630 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
631 stats.ana_statistics.dtx_action_counter);
632 EXPECT_EQ(info.ana_statistics.fec_action_counter,
633 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700634 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
635 stats.ana_statistics.frame_length_increase_counter);
636 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
637 stats.ana_statistics.frame_length_decrease_counter);
638 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
639 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800640 EXPECT_EQ(info.typing_noise_detected,
641 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700642 }
643
644 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
645 webrtc::AudioReceiveStream::Stats stats;
646 stats.remote_ssrc = 123;
647 stats.bytes_rcvd = 456;
648 stats.packets_rcvd = 768;
649 stats.packets_lost = 101;
solenberg85a04962015-10-27 03:35:21 -0700650 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100651 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700652 stats.ext_seqnum = 678;
653 stats.jitter_ms = 901;
654 stats.jitter_buffer_ms = 234;
655 stats.jitter_buffer_preferred_ms = 567;
656 stats.delay_estimate_ms = 890;
657 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700658 stats.total_samples_received = 5678901;
659 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200660 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200661 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100662 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.expand_rate = 5.67f;
664 stats.speech_expand_rate = 8.90f;
665 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200666 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700667 stats.accelerate_rate = 4.56f;
668 stats.preemptive_expand_rate = 7.89f;
669 stats.decoding_calls_to_silence_generator = 12;
670 stats.decoding_calls_to_neteq = 345;
671 stats.decoding_normal = 67890;
672 stats.decoding_plc = 1234;
673 stats.decoding_cng = 5678;
674 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700675 stats.decoding_muted_output = 3456;
676 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200677 return stats;
678 }
679 void SetAudioReceiveStreamStats() {
680 for (auto* s : call_.GetAudioReceiveStreams()) {
681 s->SetStats(GetAudioReceiveStreamStats());
682 }
683 }
684 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700685 const auto stats = GetAudioReceiveStreamStats();
686 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
687 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200688 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
689 stats.packets_rcvd);
690 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
691 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700692 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800693 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
695 stats.ext_seqnum);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
698 stats.jitter_buffer_ms);
699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700700 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
702 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700703 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700704 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
705 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200706 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200707 EXPECT_EQ(info.jitter_buffer_delay_seconds,
708 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100709 EXPECT_EQ(info.jitter_buffer_emitted_count,
710 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700711 EXPECT_EQ(info.expand_rate, stats.expand_rate);
712 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
713 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200714 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700715 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
716 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200717 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700718 stats.decoding_calls_to_silence_generator);
719 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
720 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
721 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
722 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
723 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700724 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700725 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200726 }
hbos1acfbd22016-11-17 23:43:29 -0800727 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
728 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
729 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
730 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
731 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
732 codec.ToCodecParameters());
733 }
734 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
735 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
736 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
737 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
738 codec.ToCodecParameters());
739 }
740 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200741
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100742 void VerifyGainControlEnabledCorrectly() {
743 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
744 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
745 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
746 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
747 }
748
749 void VerifyGainControlDefaultSettings() {
750 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
751 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
752 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
753 }
754
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200755 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100756 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200757 }
758
peah8271d042016-11-22 07:24:52 -0800759 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100760 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800761 }
762
Sam Zackrissonba502232019-01-04 10:36:48 +0100763 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100764 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100765 }
766
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100768 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700769 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700770 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800771 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200772 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700773 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700774 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioSendParameters send_parameters_;
776 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800777 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700778 webrtc::AudioProcessing::Config apm_config_;
779
stefanba4c0e42016-02-04 04:12:24 -0800780 private:
781 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782};
783
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100785TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700786 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787}
788
solenberg31fec402016-05-06 02:13:12 -0700789// Test that we can add a send stream and that it has the correct defaults.
790TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
791 EXPECT_TRUE(SetupChannel());
792 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800793 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
794 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
795 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700796 EXPECT_EQ("", config.rtp.c_name);
797 EXPECT_EQ(0u, config.rtp.extensions.size());
798 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
799 config.send_transport);
800}
801
802// Test that we can add a receive stream and that it has the correct defaults.
803TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
804 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800805 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700806 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800807 GetRecvStreamConfig(kSsrcX);
808 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700809 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
810 EXPECT_FALSE(config.rtp.transport_cc);
811 EXPECT_EQ(0u, config.rtp.extensions.size());
812 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
813 config.rtcp_send_transport);
814 EXPECT_EQ("", config.sync_group);
815}
816
stefanba4c0e42016-02-04 04:12:24 -0800817TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700818 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800819 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100820 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800821 if (codec.name == "opus") {
822 EXPECT_TRUE(HasTransportCc(codec));
823 opus_found = true;
824 }
825 }
826 EXPECT_TRUE(opus_found);
827}
828
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829// Test that we set our inbound codecs properly, including changing PT.
830TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200832 cricket::AudioRecvParameters parameters;
833 parameters.codecs.push_back(kIsacCodec);
834 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800835 parameters.codecs.push_back(kTelephoneEventCodec1);
836 parameters.codecs.push_back(kTelephoneEventCodec2);
837 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200838 parameters.codecs[2].id = 126;
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700841 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
842 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
843 {{0, {"PCMU", 8000, 1}},
844 {106, {"ISAC", 16000, 1}},
845 {126, {"telephone-event", 8000, 1}},
846 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
849// Test that we fail to set an unknown inbound codec.
850TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700851 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 cricket::AudioRecvParameters parameters;
853 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700854 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we fail if we have duplicate types in the inbound list.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kCn16000Codec);
864 parameters.codecs[1].id = kIsacCodec.id;
865 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866}
867
868// Test that we can decode OPUS without stereo parameters.
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 cricket::AudioRecvParameters parameters;
872 parameters.codecs.push_back(kIsacCodec);
873 parameters.codecs.push_back(kPcmuCodec);
874 parameters.codecs.push_back(kOpusCodec);
875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800876 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700877 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
878 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
879 {{0, {"PCMU", 8000, 1}},
880 {103, {"ISAC", 16000, 1}},
881 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882}
883
884// Test that we can decode OPUS with stereo = 0.
885TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700886 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 cricket::AudioRecvParameters parameters;
888 parameters.codecs.push_back(kIsacCodec);
889 parameters.codecs.push_back(kPcmuCodec);
890 parameters.codecs.push_back(kOpusCodec);
891 parameters.codecs[2].params["stereo"] = "0";
892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800893 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700894 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
895 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
896 {{0, {"PCMU", 8000, 1}},
897 {103, {"ISAC", 16000, 1}},
898 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899}
900
901// Test that we can decode OPUS with stereo = 1.
902TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700903 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 cricket::AudioRecvParameters parameters;
905 parameters.codecs.push_back(kIsacCodec);
906 parameters.codecs.push_back(kPcmuCodec);
907 parameters.codecs.push_back(kOpusCodec);
908 parameters.codecs[2].params["stereo"] = "1";
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700911 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
912 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
913 {{0, {"PCMU", 8000, 1}},
914 {103, {"ISAC", 16000, 1}},
915 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916}
917
918// Test that changes to recv codecs are applied to all streams.
919TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700920 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 cricket::AudioRecvParameters parameters;
922 parameters.codecs.push_back(kIsacCodec);
923 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800924 parameters.codecs.push_back(kTelephoneEventCodec1);
925 parameters.codecs.push_back(kTelephoneEventCodec2);
926 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200927 parameters.codecs[2].id = 126;
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700929 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
930 EXPECT_TRUE(AddRecvStream(ssrc));
931 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
932 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
933 {{0, {"PCMU", 8000, 1}},
934 {106, {"ISAC", 16000, 1}},
935 {126, {"telephone-event", 8000, 1}},
936 {107, {"telephone-event", 32000, 1}}})));
937 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
940TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700941 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 cricket::AudioRecvParameters parameters;
943 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800944 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
solenberg2100c0b2017-03-01 11:29:29 -0800947 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200948 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800949 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
952// Test that we can apply the same set of codecs again while playing.
953TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 cricket::AudioRecvParameters parameters;
956 parameters.codecs.push_back(kIsacCodec);
957 parameters.codecs.push_back(kCn16000Codec);
958 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700959 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
deadbeefcb383672017-04-26 16:28:42 -0700962 // Remapping a payload type to a different codec should fail.
963 parameters.codecs[0] = kOpusCodec;
964 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800966 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
969// Test that we can add a codec while playing.
970TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200972 cricket::AudioRecvParameters parameters;
973 parameters.codecs.push_back(kIsacCodec);
974 parameters.codecs.push_back(kCn16000Codec);
975 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700976 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 parameters.codecs.push_back(kOpusCodec);
979 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800980 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
deadbeefcb383672017-04-26 16:28:42 -0700983// Test that we accept adding the same codec with a different payload type.
984// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
985TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
986 EXPECT_TRUE(SetupRecvStream());
987 cricket::AudioRecvParameters parameters;
988 parameters.codecs.push_back(kIsacCodec);
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
990
991 ++parameters.codecs[0].id;
992 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
993}
994
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700996 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998 // Test that when autobw is enabled, bitrate is kept as the default
999 // value. autobw is enabled for the following tests because the target
1000 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001003 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
ossu20a4b3f2017-04-27 02:08:52 -07001008 // opus, default bitrate == 32000 in mono.
1009 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010}
1011
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001013 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001016 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1017 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001018 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001021 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1022 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1023 // Rates above the max (510000) should be capped.
1024 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025}
1026
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001027TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001028 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001029
1030 // Test that we can only set a maximum bitrate for a fixed-rate codec
1031 // if it's bigger than the fixed rate.
1032
1033 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001034 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1035 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001041}
1042
1043TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001044 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 const int kDesiredBitrate = 128000;
1046 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001047 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001048 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001049 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001050
Yves Gerey665174f2018-06-19 15:03:05 +02001051 EXPECT_TRUE(
1052 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001053
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001055}
1056
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057// Test that bitrate cannot be set for CBR codecs.
1058// Bitrate is ignored if it is higher than the fixed bitrate.
1059// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001060TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001061 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062
1063 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001064 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001066
1067 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001068 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001070
1071 send_parameters_.max_bandwidth_bps = 128;
1072 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001073 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074}
1075
skvlade0d46372016-04-07 22:59:22 -07001076// Test that the per-stream bitrate limit and the global
1077// bitrate limit both apply.
1078TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1079 EXPECT_TRUE(SetupSendStream());
1080
ossu20a4b3f2017-04-27 02:08:52 -07001081 // opus, default bitrate == 32000.
1082 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001083 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1084 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1085 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1086
1087 // CBR codecs allow both maximums to exceed the bitrate.
1088 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1089 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1090 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1092
1093 // CBR codecs don't allow per stream maximums to be too low.
1094 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1095 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1096}
1097
1098// Test that an attempt to set RtpParameters for a stream that does not exist
1099// fails.
1100TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1101 EXPECT_TRUE(SetupChannel());
1102 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001103 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001104 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001105
1106 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_FALSE(
1108 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001109}
1110
1111TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001113 // This test verifies that setting RtpParameters succeeds only if
1114 // the structure contains exactly one encoding.
1115 // TODO(skvlad): Update this test when we start supporting setting parameters
1116 // for each encoding individually.
1117
1118 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001119 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001120 // Two or more encodings should result in failure.
1121 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001122 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001123 // Zero encodings should also fail.
1124 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001125 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001126}
1127
1128// Changing the SSRC through RtpParameters is not allowed.
1129TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1130 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001132 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001133 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001134}
1135
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001136// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001137// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001138TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1139 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001140 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001141 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001142 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 ASSERT_EQ(1u, parameters.encodings.size());
1145 ASSERT_TRUE(parameters.encodings[0].active);
1146 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001147 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001148 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001149
1150 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001151 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001152 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001153 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001154 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001155 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001156}
1157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158// Test that SetRtpSendParameters configures the correct encoding channel for
1159// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001160TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1161 SetupForMultiSendStream();
1162 // Create send streams.
1163 for (uint32_t ssrc : kSsrcs4) {
1164 EXPECT_TRUE(
1165 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1166 }
1167 // Configure one stream to be limited by the stream config, another to be
1168 // limited by the global max, and the third one with no per-stream limit
1169 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001170 SetGlobalMaxBitrate(kOpusCodec, 32000);
1171 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1172 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1174
ossu20a4b3f2017-04-27 02:08:52 -07001175 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1176 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1177 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001178
1179 // Remove the global cap; the streams should switch to their respective
1180 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001181 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001182 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1183 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1184 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001185}
1186
Tim Haloun648d28a2018-10-18 16:52:22 -07001187// RTCRtpEncodingParameters.network_priority must be one of a few values
1188// derived from the default priority, corresponding to very-low, low, medium,
1189// or high.
1190TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1191 EXPECT_TRUE(SetupSendStream());
1192 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1193 EXPECT_EQ(1UL, parameters.encodings.size());
1194 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1195 parameters.encodings[0].network_priority);
1196
1197 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1198 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1199 for (auto it : good_values) {
1200 parameters.encodings[0].network_priority = it;
1201 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1202 }
1203 for (auto it : bad_values) {
1204 parameters.encodings[0].network_priority = it;
1205 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1206 }
1207}
1208
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209// Test that GetRtpSendParameters returns the currently configured codecs.
1210TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001211 EXPECT_TRUE(SetupSendStream());
1212 cricket::AudioSendParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001215 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001216
solenberg2100c0b2017-03-01 11:29:29 -08001217 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001219 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1220 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221}
1222
Florent Castellidacec712018-05-24 16:24:21 +02001223// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1224TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1225 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1226 params.cname = "rtcpcname";
1227 EXPECT_TRUE(SetupSendStream(params));
1228
1229 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1230 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1231}
1232
Florent Castelliabe301f2018-06-12 18:33:49 +02001233TEST_F(WebRtcVoiceEngineTestFake,
1234 DetectRtpSendParameterHeaderExtensionsChange) {
1235 EXPECT_TRUE(SetupSendStream());
1236
1237 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1238 rtp_parameters.header_extensions.emplace_back();
1239
1240 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1241
1242 webrtc::RTCError result =
1243 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1244 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1245}
1246
deadbeefcb443432016-12-12 11:12:36 -08001247// Test that GetRtpSendParameters returns an SSRC.
1248TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1249 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001250 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001251 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001252 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001253}
1254
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001255// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001256TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257 EXPECT_TRUE(SetupSendStream());
1258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kIsacCodec);
1260 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001261 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001262
solenberg2100c0b2017-03-01 11:29:29 -08001263 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
1265 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001266 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001267
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001268 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001269 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1270 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001271}
1272
minyuececec102017-03-27 13:04:25 -07001273// Test that max_bitrate_bps in send stream config gets updated correctly when
1274// SetRtpSendParameters is called.
1275TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1276 webrtc::test::ScopedFieldTrials override_field_trials(
1277 "WebRTC-Audio-SendSideBwe/Enabled/");
1278 EXPECT_TRUE(SetupSendStream());
1279 cricket::AudioSendParameters send_parameters;
1280 send_parameters.codecs.push_back(kOpusCodec);
1281 SetSendParameters(send_parameters);
1282
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1284 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1285 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1286
1287 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001288 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001289 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001290
1291 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1292 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1293}
1294
Seth Hampson24722b32017-12-22 09:36:42 -08001295// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1296// a value <= 0, setting the parameters returns false.
1297TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1298 EXPECT_TRUE(SetupSendStream());
1299 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1300 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1301 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1302 rtp_parameters.encodings[0].bitrate_priority);
1303
1304 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001305 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001306 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001307 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001308}
1309
1310// Test that the bitrate_priority in the send stream config gets updated when
1311// SetRtpSendParameters is set for the VoiceMediaChannel.
1312TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1313 EXPECT_TRUE(SetupSendStream());
1314 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1315
1316 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1317 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1318 rtp_parameters.encodings[0].bitrate_priority);
1319 double new_bitrate_priority = 2.0;
1320 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001321 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001322
1323 // The priority should get set for both the audio channel's rtp parameters
1324 // and the audio send stream's audio config.
1325 EXPECT_EQ(
1326 new_bitrate_priority,
1327 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1328 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1329}
1330
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001331// Test that GetRtpReceiveParameters returns the currently configured codecs.
1332TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1333 EXPECT_TRUE(SetupRecvStream());
1334 cricket::AudioRecvParameters parameters;
1335 parameters.codecs.push_back(kIsacCodec);
1336 parameters.codecs.push_back(kPcmuCodec);
1337 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1338
1339 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001340 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001341 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1342 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1343 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1344}
1345
deadbeefcb443432016-12-12 11:12:36 -08001346// Test that GetRtpReceiveParameters returns an SSRC.
1347TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1348 EXPECT_TRUE(SetupRecvStream());
1349 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001350 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001351 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001352 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001353}
1354
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001355// Test that if we set/get parameters multiple times, we get the same results.
1356TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1357 EXPECT_TRUE(SetupRecvStream());
1358 cricket::AudioRecvParameters parameters;
1359 parameters.codecs.push_back(kIsacCodec);
1360 parameters.codecs.push_back(kPcmuCodec);
1361 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1362
1363 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001364 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365
1366 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001367 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001368
1369 // ... And this shouldn't change the params returned by
1370 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001371 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1372 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001373}
1374
deadbeef3bc15102017-04-20 19:25:07 -07001375// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1376// aren't signaled. It should return an empty "RtpEncodingParameters" when
1377// configured to receive an unsignaled stream and no packets have been received
1378// yet, and start returning the SSRC once a packet has been received.
1379TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1380 ASSERT_TRUE(SetupChannel());
1381 // Call necessary methods to configure receiving a default stream as
1382 // soon as it arrives.
1383 cricket::AudioRecvParameters parameters;
1384 parameters.codecs.push_back(kIsacCodec);
1385 parameters.codecs.push_back(kPcmuCodec);
1386 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1387
1388 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1389 // stream. Should return nothing.
1390 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1391
1392 // Set a sink for an unsignaled stream.
1393 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1394 // Value of "0" means "unsignaled stream".
1395 channel_->SetRawAudioSink(0, std::move(fake_sink));
1396
1397 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1398 // in this method means "unsignaled stream".
1399 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1400 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1401 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1402
1403 // Receive PCMU packet (SSRC=1).
1404 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1405
1406 // The |ssrc| member should still be unset.
1407 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1408 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1409 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1410}
1411
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412// Test that we apply codecs properly.
1413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kIsacCodec);
1417 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001418 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001420 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1423 EXPECT_EQ(96, send_codec_spec.payload_type);
1424 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1425 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1426 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001427 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001428 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001429}
1430
ossu20a4b3f2017-04-27 02:08:52 -07001431// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1432// AudioSendStream.
1433TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kIsacCodec);
1437 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001438 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 parameters.codecs[0].id = 96;
1440 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001441 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001443 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001444 // Calling SetSendCodec again with same codec which is already set.
1445 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001448}
1449
ossu20a4b3f2017-04-27 02:08:52 -07001450// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1451// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001452
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001453// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 0;
1459 parameters.codecs[0].clockrate = 50000;
1460 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001463// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 0;
1469 parameters.codecs[0].channels = 0;
1470 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471}
1472
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001473// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].bitrate = 0;
1479 parameters.codecs[0].channels = 0;
1480 parameters.codecs[0].params["stereo"] = "1";
1481 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
1484// Test that if channel is 1 for opus and there's no stereo, we fail.
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].channels = 1;
1491 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001492}
1493
1494// Test that if channel is 1 for opus and stereo=0, we fail.
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001496 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001497 cricket::AudioSendParameters parameters;
1498 parameters.codecs.push_back(kOpusCodec);
1499 parameters.codecs[0].bitrate = 0;
1500 parameters.codecs[0].channels = 1;
1501 parameters.codecs[0].params["stereo"] = "0";
1502 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001503}
1504
1505// Test that if channel is 1 for opus and stereo=1, we fail.
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001507 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001508 cricket::AudioSendParameters parameters;
1509 parameters.codecs.push_back(kOpusCodec);
1510 parameters.codecs[0].bitrate = 0;
1511 parameters.codecs[0].channels = 1;
1512 parameters.codecs[0].params["stereo"] = "1";
1513 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001523 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 0;
1532 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001543 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001546 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001547
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001549 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001550 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001551}
1552
ossu20a4b3f2017-04-27 02:08:52 -07001553// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001555 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kOpusCodec);
1558 parameters.codecs[0].bitrate = 0;
1559 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001561 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
ossu20a4b3f2017-04-27 02:08:52 -07001564// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001570 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001573 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001574
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001577 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001578}
1579
ossu20a4b3f2017-04-27 02:08:52 -07001580// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001587 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1588 EXPECT_EQ(111, spec.payload_type);
1589 EXPECT_EQ(96000, spec.target_bitrate_bps);
1590 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001591 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001592 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
ossu20a4b3f2017-04-27 02:08:52 -07001595// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].bitrate = 30000;
1601 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001603 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
ossu20a4b3f2017-04-27 02:08:52 -07001606// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters parameters;
1610 parameters.codecs.push_back(kOpusCodec);
1611 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001612 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001613 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
ossu20a4b3f2017-04-27 02:08:52 -07001616// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kOpusCodec);
1621 parameters.codecs[0].bitrate = 30000;
1622 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001624 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001625}
1626
stefan13f1a0a2016-11-30 07:22:58 -08001627TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1628 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1629 200000);
1630}
1631
1632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1633 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1634}
1635
1636TEST_F(WebRtcVoiceEngineTestFake,
1637 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1638 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1639}
1640
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1642 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1643}
1644
Yves Gerey665174f2018-06-19 15:03:05 +02001645TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001646 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1647 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001648 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001649 // Setting max bitrate should keep previous min bitrate
1650 // Setting max bitrate should not reset start bitrate.
1651 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1652 SetSdpBitrateParameters(
1653 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1654 Field(&BitrateConstraints::start_bitrate_bps, -1),
1655 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001656 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001657}
1658
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001659// Test that we can enable NACK with opus as callee.
1660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 cricket::AudioSendParameters parameters;
1663 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001664 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1665 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001667 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001668 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001669 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001670
Yves Gerey665174f2018-06-19 15:03:05 +02001671 EXPECT_TRUE(
1672 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001673}
1674
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675// Test that we can enable NACK on receive streams.
1676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters parameters;
1680 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001681 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1682 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001684 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001685 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686}
1687
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688// Test that we can disable NACK on receive streams.
1689TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001690 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001691 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 cricket::AudioSendParameters parameters;
1693 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001694 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1695 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs.clear();
1700 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001702 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703}
1704
1705// Test that NACK is enabled on a new receive stream.
1706TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001707 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 cricket::AudioSendParameters parameters;
1709 parameters.codecs.push_back(kIsacCodec);
1710 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001711 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1712 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
solenberg2100c0b2017-03-01 11:29:29 -08001715 EXPECT_TRUE(AddRecvStream(kSsrcY));
1716 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1717 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1718 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719}
1720
stefanba4c0e42016-02-04 04:12:24 -08001721TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001723 cricket::AudioSendParameters send_parameters;
1724 send_parameters.codecs.push_back(kOpusCodec);
1725 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001727
1728 cricket::AudioRecvParameters recv_parameters;
1729 recv_parameters.codecs.push_back(kIsacCodec);
1730 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001731 EXPECT_TRUE(AddRecvStream(kSsrcX));
1732 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001733 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001734 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001735
ossudedfd282016-06-14 07:12:39 -07001736 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001738 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001739 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001740 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001741}
1742
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001743// Test that we can switch back and forth between Opus and ISAC with CN.
1744TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001745 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 cricket::AudioSendParameters opus_parameters;
1748 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001750 {
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(111, spec.payload_type);
1753 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters isac_parameters;
1757 isac_parameters.codecs.push_back(kIsacCodec);
1758 isac_parameters.codecs.push_back(kCn16000Codec);
1759 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001760 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001761 {
ossu20a4b3f2017-04-27 02:08:52 -07001762 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1763 EXPECT_EQ(103, spec.payload_type);
1764 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001765 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001768 {
ossu20a4b3f2017-04-27 02:08:52 -07001769 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1770 EXPECT_EQ(111, spec.payload_type);
1771 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001772 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001773}
1774
1775// Test that we handle various ways of specifying bitrate.
1776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001777 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001778 cricket::AudioSendParameters parameters;
1779 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 {
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(103, spec.payload_type);
1784 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1785 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787
Yves Gerey665174f2018-06-19 15:03:05 +02001788 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001790 {
ossu20a4b3f2017-04-27 02:08:52 -07001791 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1792 EXPECT_EQ(103, spec.payload_type);
1793 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1794 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001795 }
Yves Gerey665174f2018-06-19 15:03:05 +02001796 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001798 {
ossu20a4b3f2017-04-27 02:08:52 -07001799 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1800 EXPECT_EQ(103, spec.payload_type);
1801 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1802 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001803 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001804
Yves Gerey665174f2018-06-19 15:03:05 +02001805 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001807 {
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(0, spec.payload_type);
1810 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1811 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001812 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813
Yves Gerey665174f2018-06-19 15:03:05 +02001814 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 {
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(0, spec.payload_type);
1819 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1820 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001821 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001822
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001824 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001826 {
ossu20a4b3f2017-04-27 02:08:52 -07001827 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1828 EXPECT_EQ(111, spec.payload_type);
1829 EXPECT_STREQ("opus", spec.format.name.c_str());
1830 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832}
1833
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001834// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
1838 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001839}
1840
1841// Test that we can set send codecs even with telephone-event codec as the first
1842// one on the list.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001846 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kIsacCodec);
1848 parameters.codecs.push_back(kPcmuCodec);
1849 parameters.codecs[0].id = 98; // DTMF
1850 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001852 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1853 EXPECT_EQ(96, spec.payload_type);
1854 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001855 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001856 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001857}
1858
Harald Alvestranda1f66612018-02-21 11:24:23 +01001859// Test that CanInsertDtmf() is governed by the send flag
1860TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1861 EXPECT_TRUE(SetupSendStream());
1862 cricket::AudioSendParameters parameters;
1863 parameters.codecs.push_back(kTelephoneEventCodec1);
1864 parameters.codecs.push_back(kPcmuCodec);
1865 parameters.codecs[0].id = 98; // DTMF
1866 parameters.codecs[1].id = 96;
1867 SetSendParameters(parameters);
1868 EXPECT_FALSE(channel_->CanInsertDtmf());
1869 SetSend(true);
1870 EXPECT_TRUE(channel_->CanInsertDtmf());
1871 SetSend(false);
1872 EXPECT_FALSE(channel_->CanInsertDtmf());
1873}
1874
solenberg31642aa2016-03-14 08:00:37 -07001875// Test that payload type range is limited for telephone-event codec.
1876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001877 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001878 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001879 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001880 parameters.codecs.push_back(kIsacCodec);
1881 parameters.codecs[0].id = 0; // DTMF
1882 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001884 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001885 EXPECT_TRUE(channel_->CanInsertDtmf());
1886 parameters.codecs[0].id = 128; // DTMF
1887 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1888 EXPECT_FALSE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001890 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001891 EXPECT_TRUE(channel_->CanInsertDtmf());
1892 parameters.codecs[0].id = -1; // DTMF
1893 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1894 EXPECT_FALSE(channel_->CanInsertDtmf());
1895}
1896
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001897// Test that we can set send codecs even with CN codec as the first
1898// one on the list.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kCn16000Codec);
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
1905 parameters.codecs[0].id = 98; // wideband CN
1906 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001907 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001908 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1909 EXPECT_EQ(96, send_codec_spec.payload_type);
1910 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001911 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001912}
1913
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001914// Test that we set VAD and DTMF types correctly as caller.
1915TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001916 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001917 cricket::AudioSendParameters parameters;
1918 parameters.codecs.push_back(kIsacCodec);
1919 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001920 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs.push_back(kCn16000Codec);
1922 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001923 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 parameters.codecs[0].id = 96;
1925 parameters.codecs[2].id = 97; // wideband CN
1926 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001927 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001928 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1929 EXPECT_EQ(96, send_codec_spec.payload_type);
1930 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001931 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001932 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001933 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001934 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935}
1936
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001937// Test that we set VAD and DTMF types correctly as callee.
1938TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001939 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 cricket::AudioSendParameters parameters;
1941 parameters.codecs.push_back(kIsacCodec);
1942 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001943 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs.push_back(kCn16000Codec);
1945 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001946 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs[0].id = 96;
1948 parameters.codecs[2].id = 97; // wideband CN
1949 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001951 EXPECT_TRUE(
1952 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001953
ossu20a4b3f2017-04-27 02:08:52 -07001954 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1955 EXPECT_EQ(96, send_codec_spec.payload_type);
1956 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001957 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001958 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001959 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001960 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001961}
1962
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001963// Test that we only apply VAD if we have a CN codec that matches the
1964// send codec clockrate.
1965TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001966 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs.push_back(kIsacCodec);
1970 parameters.codecs.push_back(kCn16000Codec);
1971 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001973 {
ossu20a4b3f2017-04-27 02:08:52 -07001974 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1975 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001976 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001977 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001978 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001979 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 {
ossu20a4b3f2017-04-27 02:08:52 -07001983 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1984 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001985 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001986 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001987 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001988 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001989 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001990 {
ossu20a4b3f2017-04-27 02:08:52 -07001991 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1992 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001993 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001994 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001995 }
Brave Yao5225dd82015-03-26 07:39:19 +08001996 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001999 {
ossu20a4b3f2017-04-27 02:08:52 -07002000 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2001 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002002 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002003 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002004}
2005
2006// Test that we perform case-insensitive matching of codec names.
2007TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
2010 parameters.codecs.push_back(kIsacCodec);
2011 parameters.codecs.push_back(kPcmuCodec);
2012 parameters.codecs.push_back(kCn16000Codec);
2013 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002014 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002015 parameters.codecs[0].name = "iSaC";
2016 parameters.codecs[0].id = 96;
2017 parameters.codecs[2].id = 97; // wideband CN
2018 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002019 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002020 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2021 EXPECT_EQ(96, send_codec_spec.payload_type);
2022 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002023 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002024 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002025 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002026 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027}
2028
stefanba4c0e42016-02-04 04:12:24 -08002029class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2030 public:
2031 WebRtcVoiceEngineWithSendSideBweTest()
2032 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2033};
2034
2035TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2036 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002037 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2038 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002039 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002040 "uri", &RtpExtension::uri,
2041 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002042}
2043
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002044// Test support for audio level header extension.
2045TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002046 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002047}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002048TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002049 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002051
solenbergd4adce42016-11-17 06:26:52 -08002052// Test support for transport sequence number header extension.
2053TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2054 TestSetSendRtpHeaderExtensions(
2055 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002056}
solenbergd4adce42016-11-17 06:26:52 -08002057TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2058 TestSetRecvRtpHeaderExtensions(
2059 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060}
2061
solenberg1ac56142015-10-13 03:58:19 -07002062// Test that we can create a channel and start sending on it.
2063TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSendParameters(send_parameters_);
2066 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002067 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002068 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002070}
2071
2072// Test that a channel will send if and only if it has a source and is enabled
2073// for sending.
2074TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002075 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002076 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002077 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2080 SetAudioSend(kSsrcX, true, &fake_source_);
2081 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2082 SetAudioSend(kSsrcX, true, nullptr);
2083 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002084}
2085
solenberg94218532016-06-16 10:53:22 -07002086// Test that a channel is muted/unmuted.
2087TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2088 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002089 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2091 SetAudioSend(kSsrcX, true, nullptr);
2092 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2093 SetAudioSend(kSsrcX, false, nullptr);
2094 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002095}
2096
solenberg6d6e7c52016-04-13 09:07:30 -07002097// Test that SetSendParameters() does not alter a stream's send state.
2098TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2099 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002101
2102 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002103 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105
2106 // Changing RTP header extensions will recreate the AudioSendStream.
2107 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002108 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002109 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002110 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002111
2112 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002115
2116 // Changing RTP header extensions will recreate the AudioSendStream.
2117 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002118 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002120}
2121
solenberg1ac56142015-10-13 03:58:19 -07002122// Test that we can create a channel and start playing out on it.
2123TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002124 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002125 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002126 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002127 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002128 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130}
2131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132// Test that we can add and remove send streams.
2133TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2134 SetupForMultiSendStream();
2135
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002137 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138
solenbergc96df772015-10-21 13:01:53 -07002139 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002140 EXPECT_TRUE(
2141 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002142 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002144 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 }
tfarina5237aaf2015-11-10 23:44:30 -08002146 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147
solenbergc96df772015-10-21 13:01:53 -07002148 // Delete the send streams.
2149 for (uint32_t ssrc : kSsrcs4) {
2150 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002151 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002152 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
solenbergc96df772015-10-21 13:01:53 -07002154 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155}
2156
2157// Test SetSendCodecs correctly configure the codecs in all send streams.
2158TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2159 SetupForMultiSendStream();
2160
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002162 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002163 EXPECT_TRUE(
2164 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 }
2166
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs.push_back(kIsacCodec);
2170 parameters.codecs.push_back(kCn16000Codec);
2171 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173
2174 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002175 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002176 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2177 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002178 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2179 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002180 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002181 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002182 }
2183
minyue7a973442016-10-20 03:27:12 -07002184 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002185 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002186 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002188 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2189 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002190 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2191 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002192 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193 }
2194}
2195
2196// Test we can SetSend on all send streams correctly.
2197TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2198 SetupForMultiSendStream();
2199
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002200 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002201 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002202 EXPECT_TRUE(
2203 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002204 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002206 }
2207
2208 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002209 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002210 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002212 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 }
2214
2215 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002216 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002217 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002218 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002219 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 }
2221}
2222
2223// Test we can set the correct statistics on all send streams.
2224TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2225 SetupForMultiSendStream();
2226
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002228 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002229 EXPECT_TRUE(
2230 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231 }
solenberg85a04962015-10-27 03:35:21 -07002232
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002233 // Create a receive stream to check that none of the send streams end up in
2234 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002235 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002236
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002237 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002238 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002239 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002240 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002241
solenberg85a04962015-10-27 03:35:21 -07002242 // Check stats for the added streams.
2243 {
2244 cricket::VoiceMediaInfo info;
2245 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002246
solenberg85a04962015-10-27 03:35:21 -07002247 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002248 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002249 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002250 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002251 }
hbos1acfbd22016-11-17 23:43:29 -08002252 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002253
2254 // We have added one receive stream. We should see empty stats.
2255 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002256 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002257 }
solenberg1ac56142015-10-13 03:58:19 -07002258
solenberg2100c0b2017-03-01 11:29:29 -08002259 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002260 {
2261 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002263 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002264 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002265 EXPECT_EQ(0u, info.receivers.size());
2266 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002267
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002268 // Deliver a new packet - a default receive stream should be created and we
2269 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002270 {
2271 cricket::VoiceMediaInfo info;
2272 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2273 SetAudioReceiveStreamStats();
2274 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002275 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002276 EXPECT_EQ(1u, info.receivers.size());
2277 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002278 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002279 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002280}
2281
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282// Test that we can add and remove receive streams, and do proper send/playout.
2283// We can receive on multiple streams while sending one stream.
2284TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002285 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002286
solenberg1ac56142015-10-13 03:58:19 -07002287 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002288 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002289 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290
solenberg1ac56142015-10-13 03:58:19 -07002291 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002293 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
solenberg1ac56142015-10-13 03:58:19 -07002296 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298
2299 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2301 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2302 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
2304 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002305 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307
2308 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002309 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2311 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312
aleloi84ef6152016-08-04 05:28:21 -07002313 // Restart playout and make sure recv streams are played out.
2314 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2316 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
aleloi84ef6152016-08-04 05:28:21 -07002318 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2320 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321}
2322
wu@webrtc.org97077a32013-10-25 21:18:33 +00002323TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002324 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002325 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002326 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002327 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002328 const auto& agc_config = apm_config_.gain_controller1;
2329
2330 // Ensure default options.
2331 VerifyGainControlEnabledCorrectly();
2332 VerifyGainControlDefaultSettings();
2333
2334 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002335 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002336 EXPECT_FALSE(agc_config.enabled);
2337 send_parameters_.options.auto_gain_control = absl::nullopt;
2338
2339 send_parameters_.options.tx_agc_target_dbov = 5;
2340 SetSendParameters(send_parameters_);
2341 EXPECT_EQ(5, agc_config.target_level_dbfs);
2342 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2343
2344 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(10, agc_config.compression_gain_db);
2347 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2348
2349 send_parameters_.options.tx_agc_limiter = false;
2350 SetSendParameters(send_parameters_);
2351 EXPECT_FALSE(agc_config.enable_limiter);
2352 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2353
2354 SetSendParameters(send_parameters_);
2355 // Expect all options to have been preserved.
2356 EXPECT_FALSE(agc_config.enabled);
2357 EXPECT_EQ(5, agc_config.target_level_dbfs);
2358 EXPECT_EQ(10, agc_config.compression_gain_db);
2359 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002360}
2361
minyue6b825df2016-10-31 04:08:32 -07002362TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2363 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002364 send_parameters_.options.audio_network_adaptor = true;
2365 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002366 SetSendParameters(send_parameters_);
2367 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002368 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002369}
2370
2371TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2372 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002373 send_parameters_.options.audio_network_adaptor = true;
2374 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002375 SetSendParameters(send_parameters_);
2376 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002377 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002378 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002379 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002380 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002381 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002382}
2383
2384TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2385 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002386 send_parameters_.options.audio_network_adaptor = true;
2387 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002388 SetSendParameters(send_parameters_);
2389 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002391 const int initial_num = call_.GetNumCreatedSendStreams();
2392 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002393 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002394 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2395 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002396 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002397 // AudioSendStream not expected to be recreated.
2398 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2399 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002400 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002401}
2402
michaelt6672b262017-01-11 10:17:59 -08002403class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2404 : public WebRtcVoiceEngineTestFake {
2405 public:
2406 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2407 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002408 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2409 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002410 "Enabled/") {}
2411};
2412
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002414// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002416 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002417 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2421 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002423 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002424 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002425 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002426 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002427 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002428 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429
solenberg85a04962015-10-27 03:35:21 -07002430 // Check stats for the added streams.
2431 {
2432 cricket::VoiceMediaInfo info;
2433 EXPECT_EQ(true, channel_->GetStats(&info));
2434
2435 // We have added one send stream. We should see the stats we've set.
2436 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002437 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002438 // We have added one receive stream. We should see empty stats.
2439 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002440 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002441 }
solenberg1ac56142015-10-13 03:58:19 -07002442
solenberg566ef242015-11-06 15:34:49 -08002443 // Start sending - this affects some reported stats.
2444 {
2445 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002446 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002447 EXPECT_EQ(true, channel_->GetStats(&info));
2448 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002449 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002450 }
2451
solenberg2100c0b2017-03-01 11:29:29 -08002452 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002453 {
2454 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002455 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002456 EXPECT_EQ(true, channel_->GetStats(&info));
2457 EXPECT_EQ(1u, info.senders.size());
2458 EXPECT_EQ(0u, info.receivers.size());
2459 }
solenberg1ac56142015-10-13 03:58:19 -07002460
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002461 // Deliver a new packet - a default receive stream should be created and we
2462 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002463 {
2464 cricket::VoiceMediaInfo info;
2465 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2466 SetAudioReceiveStreamStats();
2467 EXPECT_EQ(true, channel_->GetStats(&info));
2468 EXPECT_EQ(1u, info.senders.size());
2469 EXPECT_EQ(1u, info.receivers.size());
2470 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002471 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002472 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473}
2474
2475// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002476// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002478 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2480 EXPECT_TRUE(AddRecvStream(kSsrcY));
2481 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482}
2483
2484// Test that the local SSRC is the same on sending and receiving channels if the
2485// receive channel is created before the send channel.
2486TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002489 EXPECT_TRUE(
2490 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002491 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2492 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002493}
2494
2495// Test that we can properly receive packets.
2496TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002497 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002498 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002500
Yves Gerey665174f2018-06-19 15:03:05 +02002501 EXPECT_TRUE(
2502 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503}
2504
2505// Test that we can properly receive packets on multiple streams.
2506TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002507 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002508 const uint32_t ssrc1 = 1;
2509 const uint32_t ssrc2 = 2;
2510 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002511 EXPECT_TRUE(AddRecvStream(ssrc1));
2512 EXPECT_TRUE(AddRecvStream(ssrc2));
2513 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002514 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002515 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002516 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002517 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002518 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519 }
mflodman3d7db262016-04-29 00:57:13 -07002520
2521 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2522 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2523 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2524
2525 EXPECT_EQ(s1.received_packets(), 0);
2526 EXPECT_EQ(s2.received_packets(), 0);
2527 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002528
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002530 EXPECT_EQ(s1.received_packets(), 0);
2531 EXPECT_EQ(s2.received_packets(), 0);
2532 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002533
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_EQ(s1.received_packets(), 1);
2536 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2537 EXPECT_EQ(s2.received_packets(), 0);
2538 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002539
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002541 EXPECT_EQ(s1.received_packets(), 1);
2542 EXPECT_EQ(s2.received_packets(), 1);
2543 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2544 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002545
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002547 EXPECT_EQ(s1.received_packets(), 1);
2548 EXPECT_EQ(s2.received_packets(), 1);
2549 EXPECT_EQ(s3.received_packets(), 1);
2550 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002551
mflodman3d7db262016-04-29 00:57:13 -07002552 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2553 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2554 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555}
2556
solenberg2100c0b2017-03-01 11:29:29 -08002557// Test that receiving on an unsignaled stream works (a stream is created).
2558TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002559 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002560 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002561
solenberg7e63ef02015-11-20 00:19:43 -08002562 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002563
Mirko Bonadeif859e552018-05-30 15:31:29 +02002564 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002565 EXPECT_TRUE(
2566 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002567}
2568
Seth Hampson5897a6e2018-04-03 11:16:33 -07002569// Tests that when we add a stream without SSRCs, but contains a stream_id
2570// that it is stored and its stream id is later used when the first packet
2571// arrives to properly create a receive stream with a sync label.
2572TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2573 const char kSyncLabel[] = "sync_label";
2574 EXPECT_TRUE(SetupChannel());
2575 cricket::StreamParams unsignaled_stream;
2576 unsignaled_stream.set_stream_ids({kSyncLabel});
2577 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2578 // The stream shouldn't have been created at this point because it doesn't
2579 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002580 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002581
2582 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2583
Mirko Bonadeif859e552018-05-30 15:31:29 +02002584 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002585 EXPECT_TRUE(
2586 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2587 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2588
2589 // Removing the unsignaled stream clears the cached parameters. If a new
2590 // default unsignaled receive stream is created it will not have a sync group.
2591 channel_->RemoveRecvStream(0);
2592 channel_->RemoveRecvStream(kSsrc1);
2593
2594 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2595
Mirko Bonadeif859e552018-05-30 15:31:29 +02002596 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002597 EXPECT_TRUE(
2598 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2599 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2600}
2601
solenberg2100c0b2017-03-01 11:29:29 -08002602// Test that receiving N unsignaled stream works (streams will be created), and
2603// that packets are forwarded to them all.
2604TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002605 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002606 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002607 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2608
solenberg2100c0b2017-03-01 11:29:29 -08002609 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002610 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002611 rtc::SetBE32(&packet[8], ssrc);
2612 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002613
solenberg2100c0b2017-03-01 11:29:29 -08002614 // Verify we have one new stream for each loop iteration.
2615 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002616 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2617 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002618 }
mflodman3d7db262016-04-29 00:57:13 -07002619
solenberg2100c0b2017-03-01 11:29:29 -08002620 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002621 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002622 rtc::SetBE32(&packet[8], ssrc);
2623 DeliverPacket(packet, sizeof(packet));
2624
solenbergebb349d2017-03-13 05:46:15 -07002625 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002626 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2627 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2628 }
2629
2630 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2631 constexpr uint32_t kAnotherSsrc = 667;
2632 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002633 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002634
2635 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002636 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002637 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002638 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002639 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2640 EXPECT_EQ(2, streams[i]->received_packets());
2641 }
2642 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2643 EXPECT_EQ(1, streams[i]->received_packets());
2644 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002645 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002646}
2647
solenberg2100c0b2017-03-01 11:29:29 -08002648// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002649// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002650TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002652 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002653 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2654
2655 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002656 const uint32_t signaled_ssrc = 1;
2657 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002658 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002659 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002660 EXPECT_TRUE(
2661 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002662 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002663
2664 // Note that the first unknown SSRC cannot be 0, because we only support
2665 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002666 const uint32_t unsignaled_ssrc = 7011;
2667 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002668 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002669 EXPECT_TRUE(
2670 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002671 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002672
2673 DeliverPacket(packet, sizeof(packet));
2674 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2675
2676 rtc::SetBE32(&packet[8], signaled_ssrc);
2677 DeliverPacket(packet, sizeof(packet));
2678 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002679 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002680}
2681
solenberg4904fb62017-02-17 12:01:14 -08002682// Two tests to verify that adding a receive stream with the same SSRC as a
2683// previously added unsignaled stream will only recreate underlying stream
2684// objects if the stream parameters have changed.
2685TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2686 EXPECT_TRUE(SetupChannel());
2687
2688 // Spawn unsignaled stream with SSRC=1.
2689 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002690 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002691 EXPECT_TRUE(
2692 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002693
2694 // Verify that the underlying stream object in Call is not recreated when a
2695 // stream with SSRC=1 is added.
2696 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002697 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002698 int audio_receive_stream_id = streams.front()->id();
2699 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002700 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002701 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2702}
2703
2704TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2705 EXPECT_TRUE(SetupChannel());
2706
2707 // Spawn unsignaled stream with SSRC=1.
2708 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002709 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002710 EXPECT_TRUE(
2711 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002712
2713 // Verify that the underlying stream object in Call *is* recreated when a
2714 // stream with SSRC=1 is added, and which has changed stream parameters.
2715 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002716 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002717 int audio_receive_stream_id = streams.front()->id();
2718 cricket::StreamParams stream_params;
2719 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002720 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002721 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002723 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2724}
2725
solenberg1ac56142015-10-13 03:58:19 -07002726// Test that AddRecvStream creates new stream.
2727TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002728 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002729 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730}
2731
2732// Test that after adding a recv stream, we do not decode more codecs than
2733// those previously passed into SetRecvCodecs.
2734TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002735 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002736 cricket::AudioRecvParameters parameters;
2737 parameters.codecs.push_back(kIsacCodec);
2738 parameters.codecs.push_back(kPcmuCodec);
2739 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002740 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002741 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2742 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2743 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744}
2745
2746// Test that we properly clean up any streams that were added, even if
2747// not explicitly removed.
2748TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002749 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002750 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002751 EXPECT_TRUE(AddRecvStream(1));
2752 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002753
Mirko Bonadeif859e552018-05-30 15:31:29 +02002754 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2755 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002756 delete channel_;
2757 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002758 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2759 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760}
2761
wu@webrtc.org78187522013-10-07 23:32:02 +00002762TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002763 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002764 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002765}
2766
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002767TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002768 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002769 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002770 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002771}
2772
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002773// Test the InsertDtmf on default send stream as caller.
2774TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002775 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776}
2777
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002778// Test the InsertDtmf on default send stream as callee
2779TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002780 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002781}
2782
2783// Test the InsertDtmf on specified send stream as caller.
2784TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002785 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002786}
2787
2788// Test the InsertDtmf on specified send stream as callee.
2789TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002790 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
Johannes Kron9190b822018-10-29 11:22:05 +01002793// Test propagation of extmap allow mixed setting.
2794TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2795 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2796}
2797TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2798 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2799}
2800TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2801 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2802}
2803TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2804 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2805}
2806
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002808 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002809 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002810 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002811 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002812 .WillRepeatedly(Return(false));
2813 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2814 .Times(4)
2815 .WillRepeatedly(Return(false));
2816 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2817 .Times(2)
2818 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002819
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002820 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002821 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822
solenberg246b8172015-12-08 09:50:23 -08002823 // Nothing set in AudioOptions, so everything should be as default.
2824 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002825 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002826 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002827 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002828 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002829 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002830 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831
Sam Zackrissonba502232019-01-04 10:36:48 +01002832 // Turn typing detection off.
2833 send_parameters_.options.typing_detection = false;
2834 SetSendParameters(send_parameters_);
2835 EXPECT_FALSE(IsTypingDetectionEnabled());
2836
2837 // Leave typing detection unchanged, but non-default.
2838 send_parameters_.options.typing_detection = absl::nullopt;
2839 SetSendParameters(send_parameters_);
2840 EXPECT_FALSE(IsTypingDetectionEnabled());
2841
2842 // Turn typing detection on.
2843 send_parameters_.options.typing_detection = true;
2844 SetSendParameters(send_parameters_);
2845 EXPECT_TRUE(IsTypingDetectionEnabled());
2846
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002847 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002848 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002849 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002850 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002851
2852 // Turn echo cancellation back on, with settings, and make sure
2853 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002854 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002855 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002856 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002857
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002858 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002859 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002860 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002861 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002862
Per Åhgrenf40a3402019-04-25 08:50:11 +02002863 // Restore AEC to be on to work with the following tests.
2864 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002865 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002866
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002868 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002869 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002870 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002871 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002872
2873 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002874 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002875 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002876 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002877 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002879 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002880 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002881 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002882 send_parameters_.options.noise_suppression = false;
2883 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002885 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002886 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002887 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002888 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
solenberg1ac56142015-10-13 03:58:19 -07002890 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002891 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002892 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002893 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002894 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002895 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896}
2897
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002899 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002900 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2901 .Times(8)
2902 .WillRepeatedly(Return(false));
2903 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2904 .Times(8)
2905 .WillRepeatedly(Return(false));
2906 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2907 .Times(8)
2908 .WillRepeatedly(Return(false));
2909 EXPECT_CALL(adm_, RecordingIsInitialized())
2910 .Times(2)
2911 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002912 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2913 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002914 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002915
kwiberg686a8ef2016-02-26 03:00:35 -08002916 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002917 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2918 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2919 cricket::AudioOptions(),
2920 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002921 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002922 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2923 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2924 cricket::AudioOptions(),
2925 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926
2927 // Have to add a stream to make SetSend work.
2928 cricket::StreamParams stream1;
2929 stream1.ssrcs.push_back(1);
2930 channel1->AddSendStream(stream1);
2931 cricket::StreamParams stream2;
2932 stream2.ssrcs.push_back(2);
2933 channel2->AddSendStream(stream2);
2934
2935 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002937 parameters_options_all.options.echo_cancellation = true;
2938 parameters_options_all.options.auto_gain_control = true;
2939 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002940 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002941 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002942 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002943 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002944 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002946 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002947 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002948 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002949 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002950
2951 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002952 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002953 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002954 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002955 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002956 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002957 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002958 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002960 expected_options.echo_cancellation = true;
2961 expected_options.auto_gain_control = true;
2962 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002963 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002964
2965 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002966 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002967 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002968 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002969 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002970 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002971 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002972 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002973 expected_options.echo_cancellation = true;
2974 expected_options.auto_gain_control = false;
2975 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002976 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002980 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002981 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002982 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002984 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002985 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002986 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002987 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002988 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002990 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002991 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002992 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002993 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002994 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002997 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2998 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002999 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3000 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003001 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003002 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003003 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003004 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003005 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003006 expected_options.echo_cancellation = true;
3007 expected_options.auto_gain_control = false;
3008 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003009 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010}
3011
wu@webrtc.orgde305012013-10-31 15:40:38 +00003012// This test verifies DSCP settings are properly applied on voice media channel.
3013TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003014 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003015 cricket::FakeNetworkInterface network_interface;
3016 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003017 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003018 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003019
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003020 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003021
Sebastian Jansson84848f22018-11-16 10:40:36 +01003022 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3023 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3024 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003025 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003026 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3027 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3028
3029 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003030 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3031 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3032 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003033 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003034 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3035
3036 // Create a send stream to configure
3037 EXPECT_TRUE(
3038 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3039 parameters = channel->GetRtpSendParameters(kSsrcZ);
3040 ASSERT_FALSE(parameters.encodings.empty());
3041
3042 // Various priorities map to various dscp values.
3043 parameters.encodings[0].network_priority = 4.0;
3044 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003045 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003046 parameters.encodings[0].network_priority = 0.5;
3047 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3048 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3049
3050 // A bad priority does not change the dscp value.
3051 parameters.encodings[0].network_priority = 0.0;
3052 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3053 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003054
Tim Haloun6ca98362018-09-17 17:06:08 -07003055 // Packets should also self-identify their dscp in PacketOptions.
3056 const uint8_t kData[10] = {0};
3057 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003058 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003059
nisse51542be2016-02-12 02:27:06 -08003060 // Verify that setting the option to false resets the
3061 // DiffServCodePoint.
3062 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003063 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3064 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3065 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003066 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003067 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3068 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3069
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003070 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003071}
3072
solenberg4bac9c52015-10-09 02:32:53 -07003073TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003074 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003075 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003076 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003077 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003078 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003079 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3080 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3081 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003082}
3083
solenberg2100c0b2017-03-01 11:29:29 -08003084TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003085 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003086
3087 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003088 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003089 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3090
3091 // Should remember the volume "2" which will be set on new unsignaled streams,
3092 // and also set the gain to 2 on existing unsignaled streams.
3093 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3094 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3095
3096 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3097 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3098 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3099 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3100 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3101 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3102
3103 // Setting gain with SSRC=0 should affect all unsignaled streams.
3104 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003105 if (kMaxUnsignaledRecvStreams > 1) {
3106 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3107 }
solenberg2100c0b2017-03-01 11:29:29 -08003108 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3109
3110 // Setting gain on an individual stream affects only that.
3111 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003112 if (kMaxUnsignaledRecvStreams > 1) {
3113 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3114 }
solenberg2100c0b2017-03-01 11:29:29 -08003115 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003116}
3117
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003118TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3119 EXPECT_TRUE(SetupChannel());
3120 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3121 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3122
3123 cricket::StreamParams stream;
3124 stream.ssrcs.push_back(kSsrcY);
3125 EXPECT_TRUE(channel_->AddRecvStream(stream));
3126 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3127 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3128 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3129}
3130
3131TEST_F(WebRtcVoiceEngineTestFake,
3132 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3133 // Here base minimum delay is abbreviated to delay in comments for shortness.
3134 EXPECT_TRUE(SetupChannel());
3135
3136 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3137 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3138 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3139 // Check that it doesn't provide default values for unknown ssrc.
3140 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3141
3142 // Check that default value for unsignaled streams is 0.
3143 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3144
3145 // Should remember the delay 100 which will be set on new unsignaled streams,
3146 // and also set the delay to 100 on existing unsignaled streams.
3147 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3148 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3149 // Check that it doesn't provide default values for unknown ssrc.
3150 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3151
3152 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3153 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3154 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3155 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3156 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3157 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3158
3159 // Setting delay with SSRC=0 should affect all unsignaled streams.
3160 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3161 if (kMaxUnsignaledRecvStreams > 1) {
3162 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3163 }
3164 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3165
3166 // Setting delay on an individual stream affects only that.
3167 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3168 if (kMaxUnsignaledRecvStreams > 1) {
3169 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3170 }
3171 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3172 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3173 // Check that it doesn't provide default values for unknown ssrc.
3174 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3175}
3176
Seth Hampson845e8782018-03-02 11:34:10 -08003177TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003178 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003179 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003180
solenbergff976312016-03-30 23:28:51 -07003181 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003182 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003183 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003184 // Creating two channels to make sure that sync label is set properly for both
3185 // the default voice channel and following ones.
3186 EXPECT_TRUE(channel_->AddRecvStream(sp));
3187 sp.ssrcs[0] += 1;
3188 EXPECT_TRUE(channel_->AddRecvStream(sp));
3189
Mirko Bonadeif859e552018-05-30 15:31:29 +02003190 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003191 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003192 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003193 << "SyncGroup should be set based on stream id";
3194 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003195 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003196 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003197}
3198
solenberg3a941542015-11-16 07:34:50 -08003199// TODO(solenberg): Remove, once recv streams are configured through Call.
3200// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003201TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003202 // Test that setting the header extensions results in the expected state
3203 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003204 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003205 ssrcs.push_back(223);
3206 ssrcs.push_back(224);
3207
solenbergff976312016-03-30 23:28:51 -07003208 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003209 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003210 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003211 EXPECT_TRUE(
3212 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003213 }
3214
Mirko Bonadeif859e552018-05-30 15:31:29 +02003215 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003216 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003217 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003218 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003219 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003220 }
3221
3222 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003223 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003224 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003225 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003226 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003227 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003228 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003229 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003230 EXPECT_NE(nullptr, s);
3231 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003232 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3233 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003234 for (const auto& s_ext : s_exts) {
3235 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003236 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003237 }
3238 }
3239 }
3240 }
3241
3242 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003243 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003244 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003245 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003246 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003247 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003248 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003249}
3250
3251TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3252 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003253 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003254 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003256 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3257 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003259 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003260
solenbergff976312016-03-30 23:28:51 -07003261 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003262 cricket::WebRtcVoiceMediaChannel* media_channel =
3263 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003264 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003265 EXPECT_TRUE(media_channel->AddRecvStream(
3266 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3267
Mirko Bonadeif859e552018-05-30 15:31:29 +02003268 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003270 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003272 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003274 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003276}
Minyue2013aec2015-05-13 14:14:42 +02003277
solenberg0a617e22015-10-20 15:49:38 -07003278// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003279// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003280TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003281 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003282 EXPECT_TRUE(AddRecvStream(kSsrcY));
3283 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003284 EXPECT_TRUE(
3285 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3287 EXPECT_TRUE(AddRecvStream(kSsrcW));
3288 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003289}
3290
solenberg7602aab2016-11-14 11:30:07 -08003291TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3292 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003293 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003294 EXPECT_TRUE(
3295 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003296 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3297 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3298 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003299 EXPECT_TRUE(
3300 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003301 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3302 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003303}
stefan658910c2015-09-03 05:48:32 -07003304
deadbeef884f5852016-01-15 09:20:04 -08003305TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003306 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003307 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3308 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003309
3310 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003311 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3312 EXPECT_TRUE(AddRecvStream(kSsrcX));
3313 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003314
3315 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003316 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3317 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003318
3319 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003320 channel_->SetRawAudioSink(kSsrcX, nullptr);
3321 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003322}
3323
solenberg2100c0b2017-03-01 11:29:29 -08003324TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003325 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003326 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3327 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003328 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3329 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003330
3331 // Should be able to set a default sink even when no stream exists.
3332 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3333
solenberg2100c0b2017-03-01 11:29:29 -08003334 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3335 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003336 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003337 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003338
3339 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003340 channel_->SetRawAudioSink(kSsrc0, nullptr);
3341 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003342
3343 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003344 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3345 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003346
3347 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003349 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003350 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3351
3352 // Spawn another unsignaled stream - it should be assigned the default sink
3353 // and the previous unsignaled stream should lose it.
3354 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3355 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3356 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3357 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003358 if (kMaxUnsignaledRecvStreams > 1) {
3359 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3360 }
solenberg2100c0b2017-03-01 11:29:29 -08003361 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3362
3363 // Reset the default sink - the second unsignaled stream should lose it.
3364 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003365 if (kMaxUnsignaledRecvStreams > 1) {
3366 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3367 }
solenberg2100c0b2017-03-01 11:29:29 -08003368 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3369
3370 // Try setting the default sink while two streams exists.
3371 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003372 if (kMaxUnsignaledRecvStreams > 1) {
3373 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3374 }
solenberg2100c0b2017-03-01 11:29:29 -08003375 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3376
3377 // Try setting the sink for the first unsignaled stream using its known SSRC.
3378 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003379 if (kMaxUnsignaledRecvStreams > 1) {
3380 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3381 }
solenberg2100c0b2017-03-01 11:29:29 -08003382 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003383 if (kMaxUnsignaledRecvStreams > 1) {
3384 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3385 }
deadbeef884f5852016-01-15 09:20:04 -08003386}
3387
skvlad7a43d252016-03-22 15:32:27 -07003388// Test that, just like the video channel, the voice channel communicates the
3389// network state to the call.
3390TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003391 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003392
3393 EXPECT_EQ(webrtc::kNetworkUp,
3394 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3395 EXPECT_EQ(webrtc::kNetworkUp,
3396 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3397
3398 channel_->OnReadyToSend(false);
3399 EXPECT_EQ(webrtc::kNetworkDown,
3400 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3401 EXPECT_EQ(webrtc::kNetworkUp,
3402 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3403
3404 channel_->OnReadyToSend(true);
3405 EXPECT_EQ(webrtc::kNetworkUp,
3406 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3407 EXPECT_EQ(webrtc::kNetworkUp,
3408 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3409}
3410
aleloi18e0b672016-10-04 02:45:47 -07003411// Test that playout is still started after changing parameters
3412TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3413 SetupRecvStream();
3414 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003415 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003416
3417 // Changing RTP header extensions will recreate the AudioReceiveStream.
3418 cricket::AudioRecvParameters parameters;
3419 parameters.extensions.push_back(
3420 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3421 channel_->SetRecvParameters(parameters);
3422
solenberg2100c0b2017-03-01 11:29:29 -08003423 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003424}
3425
Zhi Huangfa266ef2017-12-13 10:27:46 -08003426// Tests when GetSources is called with non-existing ssrc, it will return an
3427// empty list of RtpSource without crashing.
3428TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3429 // Setup an recv stream with |kSsrcX|.
3430 SetupRecvStream();
3431 cricket::WebRtcVoiceMediaChannel* media_channel =
3432 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3433 // Call GetSources with |kSsrcY| which doesn't exist.
3434 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3435 EXPECT_EQ(0u, sources.size());
3436}
3437
stefan658910c2015-09-03 05:48:32 -07003438// Tests that the library initializes and shuts down properly.
3439TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003440 // If the VoiceEngine wants to gather available codecs early, that's fine but
3441 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003442 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3443 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003444 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003445 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003446 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003447 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003448 task_queue_factory.get(), &adm,
3449 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003450 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003451 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003452 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003453 webrtc::Call::Config call_config(&event_log);
3454 call_config.task_queue_factory = task_queue_factory.get();
3455 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003456 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3457 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3458 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003459 EXPECT_TRUE(channel != nullptr);
3460 delete channel;
solenbergff976312016-03-30 23:28:51 -07003461}
stefan658910c2015-09-03 05:48:32 -07003462
solenbergff976312016-03-30 23:28:51 -07003463// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003464TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003465 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3466 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003467 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003468 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003469 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003470 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003471 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003472 {
peaha9cc40b2017-06-29 08:32:09 -07003473 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003474 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003475 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003476 task_queue_factory.get(), &adm,
3477 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003478 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003479 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003480 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003481 webrtc::Call::Config call_config(&event_log);
3482 call_config.task_queue_factory = task_queue_factory.get();
3483 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003484 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3485 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3486 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003487 EXPECT_TRUE(channel != nullptr);
3488 delete channel;
3489 }
stefan658910c2015-09-03 05:48:32 -07003490}
3491
ossu20a4b3f2017-04-27 02:08:52 -07003492// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3493TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003494 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3495 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003496 // TODO(ossu): Why are the payload types of codecs with non-static payload
3497 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003498 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003499 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003500 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003501 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003502 task_queue_factory.get(), &adm,
3503 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003504 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003505 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003506 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003507 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003508 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003509 (clockrate == 0 || codec.clockrate == clockrate);
3510 };
3511 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003512 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003513 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003514 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003515 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003516 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003517 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003518 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003519 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003520 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003521 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003522 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003523 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3524 // Remove these checks once both send and receive side assigns payload
3525 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003526 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003527 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003528 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003529 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003530 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003531 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003532 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003533 EXPECT_EQ(111, codec.id);
3534 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3535 EXPECT_EQ("10", codec.params.find("minptime")->second);
3536 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3537 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003538 }
3539 }
stefan658910c2015-09-03 05:48:32 -07003540}
3541
3542// Tests that VoE supports at least 32 channels
3543TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003544 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3545 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003546 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003547 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003548 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003549 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003550 task_queue_factory.get(), &adm,
3551 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003552 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003553 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003554 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003555 webrtc::Call::Config call_config(&event_log);
3556 call_config.task_queue_factory = task_queue_factory.get();
3557 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
stefan658910c2015-09-03 05:48:32 -07003558
3559 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003560 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003561 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003562 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3563 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3564 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003565 if (!channel)
3566 break;
stefan658910c2015-09-03 05:48:32 -07003567 channels[num_channels++] = channel;
3568 }
3569
Mirko Bonadeif859e552018-05-30 15:31:29 +02003570 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003571 EXPECT_EQ(expected, num_channels);
3572
3573 while (num_channels > 0) {
3574 delete channels[--num_channels];
3575 }
stefan658910c2015-09-03 05:48:32 -07003576}
3577
3578// Test that we set our preferred codecs properly.
3579TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003580 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3581 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003582 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3583 // - Check that our builtin codecs are usable by Channel.
3584 // - The codecs provided by the engine is usable by Channel.
3585 // It does not check that the codecs in the RecvParameters are actually
3586 // what we sent in - though it's probably reasonable to expect so, if
3587 // SetRecvParameters returns true.
3588 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003589 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003590 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003591 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003592 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003593 task_queue_factory.get(), &adm,
3594 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003595 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003596 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003597 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003598 webrtc::Call::Config call_config(&event_log);
3599 call_config.task_queue_factory = task_queue_factory.get();
3600 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
nisse51542be2016-02-12 02:27:06 -08003601 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003602 cricket::AudioOptions(),
3603 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003604 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003605 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003606 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003607}
ossu9def8002017-02-09 05:14:32 -08003608
3609TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3610 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003611 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3612 {48000, 2, 16000, 10000, 20000}};
3613 spec1.info.allow_comfort_noise = false;
3614 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003615 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003616 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3617 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003618 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003619 specs.push_back(webrtc::AudioCodecSpec{
3620 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3621 {16000, 1, 13300}});
3622 specs.push_back(
3623 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3624 specs.push_back(
3625 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003626
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003627 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3628 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003629 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3630 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3631 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003632 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003633 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003634 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003635 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003636
peaha9cc40b2017-06-29 08:32:09 -07003637 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003638 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003639 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3640 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003641 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003642 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003643 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003644 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003645
3646 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3647 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003648 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3649 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3650 if (codecs.size() > index)
3651 return codecs[index];
3652 return missing_codec;
3653 };
ossu9def8002017-02-09 05:14:32 -08003654
3655 // Ensure the general codecs are generated first and in order.
3656 for (size_t i = 0; i != specs.size(); ++i) {
3657 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3658 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3659 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3660 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3661 }
3662
3663 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003664 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003665 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3666 for (size_t i = 0; i != codecs.size(); ++i) {
3667 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003668 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003669 codec.clockrate == format.clockrate_hz &&
3670 codec.channels == format.num_channels) {
3671 return rtc::checked_cast<int>(i);
3672 }
3673 }
3674 return -1;
3675 };
ossu9def8002017-02-09 05:14:32 -08003676
3677 // Ensure all supplementary codecs are generated last. Their internal ordering
3678 // is not important.
3679 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3680 const int num_specs = static_cast<int>(specs.size());
3681 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3682 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3683 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3684 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3685 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3686 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3687 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3688}