blob: 9556e5f662f51f6ae593477819958a4e0a815351 [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;
Alex Narest5b5d97c2019-08-07 18:15:08 +0200673 stats.decoding_codec_plc = 1236;
solenberg85a04962015-10-27 03:35:21 -0700674 stats.decoding_cng = 5678;
675 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700676 stats.decoding_muted_output = 3456;
677 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200678 return stats;
679 }
680 void SetAudioReceiveStreamStats() {
681 for (auto* s : call_.GetAudioReceiveStreams()) {
682 s->SetStats(GetAudioReceiveStreamStats());
683 }
684 }
685 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700686 const auto stats = GetAudioReceiveStreamStats();
687 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
688 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200689 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
690 stats.packets_rcvd);
691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
692 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700693 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800694 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
696 stats.ext_seqnum);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
699 stats.jitter_buffer_ms);
700 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700701 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200702 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
703 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700704 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700705 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
706 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200707 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200708 EXPECT_EQ(info.jitter_buffer_delay_seconds,
709 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100710 EXPECT_EQ(info.jitter_buffer_emitted_count,
711 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700712 EXPECT_EQ(info.expand_rate, stats.expand_rate);
713 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
714 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200715 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700716 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
717 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200718 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700719 stats.decoding_calls_to_silence_generator);
720 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
721 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
722 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
Alex Narest5b5d97c2019-08-07 18:15:08 +0200723 EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
solenberg85a04962015-10-27 03:35:21 -0700724 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
725 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700726 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700727 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200728 }
hbos1acfbd22016-11-17 23:43:29 -0800729 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
730 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
731 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
732 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
733 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
734 codec.ToCodecParameters());
735 }
736 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
737 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
738 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
739 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
740 codec.ToCodecParameters());
741 }
742 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200743
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100744 void VerifyGainControlEnabledCorrectly() {
745 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
746 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
747 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
748 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
749 }
750
751 void VerifyGainControlDefaultSettings() {
752 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
753 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
754 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
755 }
756
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200757 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100758 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200759 }
760
peah8271d042016-11-22 07:24:52 -0800761 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100762 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800763 }
764
Sam Zackrissonba502232019-01-04 10:36:48 +0100765 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100766 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100767 }
768
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100770 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700771 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700772 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800773 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200774 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700775 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700776 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 cricket::AudioSendParameters send_parameters_;
778 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800779 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700780 webrtc::AudioProcessing::Config apm_config_;
781
stefanba4c0e42016-02-04 04:12:24 -0800782 private:
783 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784};
785
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100787TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
solenberg31fec402016-05-06 02:13:12 -0700791// Test that we can add a send stream and that it has the correct defaults.
792TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
793 EXPECT_TRUE(SetupChannel());
794 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800795 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
796 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
797 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700798 EXPECT_EQ("", config.rtp.c_name);
799 EXPECT_EQ(0u, config.rtp.extensions.size());
800 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
801 config.send_transport);
802}
803
804// Test that we can add a receive stream and that it has the correct defaults.
805TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
806 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800807 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700808 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800809 GetRecvStreamConfig(kSsrcX);
810 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700811 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
812 EXPECT_FALSE(config.rtp.transport_cc);
813 EXPECT_EQ(0u, config.rtp.extensions.size());
814 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
815 config.rtcp_send_transport);
816 EXPECT_EQ("", config.sync_group);
817}
818
stefanba4c0e42016-02-04 04:12:24 -0800819TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700820 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800821 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100822 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800823 if (codec.name == "opus") {
824 EXPECT_TRUE(HasTransportCc(codec));
825 opus_found = true;
826 }
827 }
828 EXPECT_TRUE(opus_found);
829}
830
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831// Test that we set our inbound codecs properly, including changing PT.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800837 parameters.codecs.push_back(kTelephoneEventCodec1);
838 parameters.codecs.push_back(kTelephoneEventCodec2);
839 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 parameters.codecs[2].id = 126;
841 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800842 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700843 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
844 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
845 {{0, {"PCMU", 8000, 1}},
846 {106, {"ISAC", 16000, 1}},
847 {126, {"telephone-event", 8000, 1}},
848 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849}
850
851// Test that we fail to set an unknown inbound codec.
852TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700853 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200854 cricket::AudioRecvParameters parameters;
855 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700856 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we fail if we have duplicate types in the inbound list.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kCn16000Codec);
866 parameters.codecs[1].id = kIsacCodec.id;
867 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868}
869
870// Test that we can decode OPUS without stereo parameters.
871TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700872 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200873 cricket::AudioRecvParameters parameters;
874 parameters.codecs.push_back(kIsacCodec);
875 parameters.codecs.push_back(kPcmuCodec);
876 parameters.codecs.push_back(kOpusCodec);
877 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800878 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700879 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
880 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
881 {{0, {"PCMU", 8000, 1}},
882 {103, {"ISAC", 16000, 1}},
883 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884}
885
886// Test that we can decode OPUS with stereo = 0.
887TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700888 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 cricket::AudioRecvParameters parameters;
890 parameters.codecs.push_back(kIsacCodec);
891 parameters.codecs.push_back(kPcmuCodec);
892 parameters.codecs.push_back(kOpusCodec);
893 parameters.codecs[2].params["stereo"] = "0";
894 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800895 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700896 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
897 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
898 {{0, {"PCMU", 8000, 1}},
899 {103, {"ISAC", 16000, 1}},
900 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
903// Test that we can decode OPUS with stereo = 1.
904TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700905 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200906 cricket::AudioRecvParameters parameters;
907 parameters.codecs.push_back(kIsacCodec);
908 parameters.codecs.push_back(kPcmuCodec);
909 parameters.codecs.push_back(kOpusCodec);
910 parameters.codecs[2].params["stereo"] = "1";
911 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800912 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700913 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
914 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
915 {{0, {"PCMU", 8000, 1}},
916 {103, {"ISAC", 16000, 1}},
917 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
920// Test that changes to recv codecs are applied to all streams.
921TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700922 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200923 cricket::AudioRecvParameters parameters;
924 parameters.codecs.push_back(kIsacCodec);
925 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800926 parameters.codecs.push_back(kTelephoneEventCodec1);
927 parameters.codecs.push_back(kTelephoneEventCodec2);
928 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 parameters.codecs[2].id = 126;
930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700931 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
932 EXPECT_TRUE(AddRecvStream(ssrc));
933 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
934 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
935 {{0, {"PCMU", 8000, 1}},
936 {106, {"ISAC", 16000, 1}},
937 {126, {"telephone-event", 8000, 1}},
938 {107, {"telephone-event", 32000, 1}}})));
939 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
942TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700943 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200944 cricket::AudioRecvParameters parameters;
945 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800946 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
solenberg2100c0b2017-03-01 11:29:29 -0800949 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200950 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800951 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
954// Test that we can apply the same set of codecs again while playing.
955TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 cricket::AudioRecvParameters parameters;
958 parameters.codecs.push_back(kIsacCodec);
959 parameters.codecs.push_back(kCn16000Codec);
960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700961 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
deadbeefcb383672017-04-26 16:28:42 -0700964 // Remapping a payload type to a different codec should fail.
965 parameters.codecs[0] = kOpusCodec;
966 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200967 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800968 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
971// Test that we can add a codec while playing.
972TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700973 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200974 cricket::AudioRecvParameters parameters;
975 parameters.codecs.push_back(kIsacCodec);
976 parameters.codecs.push_back(kCn16000Codec);
977 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700978 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200980 parameters.codecs.push_back(kOpusCodec);
981 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800982 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983}
984
deadbeefcb383672017-04-26 16:28:42 -0700985// Test that we accept adding the same codec with a different payload type.
986// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
987TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
988 EXPECT_TRUE(SetupRecvStream());
989 cricket::AudioRecvParameters parameters;
990 parameters.codecs.push_back(kIsacCodec);
991 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
992
993 ++parameters.codecs[0].id;
994 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
995}
996
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001000 // Test that when autobw is enabled, bitrate is kept as the default
1001 // value. autobw is enabled for the following tests because the target
1002 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003
1004 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001005 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006
1007 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001008 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009
ossu20a4b3f2017-04-27 02:08:52 -07001010 // opus, default bitrate == 32000 in mono.
1011 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012}
1013
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001014TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001015 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001018 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1019 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001020 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001023 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1024 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1025 // Rates above the max (510000) should be capped.
1026 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027}
1028
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001029TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001030 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001031
1032 // Test that we can only set a maximum bitrate for a fixed-rate codec
1033 // if it's bigger than the fixed rate.
1034
1035 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001036 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1041 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1042 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001043}
1044
1045TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001046 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001047 const int kDesiredBitrate = 128000;
1048 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001049 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001050 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001051 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001052
Yves Gerey665174f2018-06-19 15:03:05 +02001053 EXPECT_TRUE(
1054 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001055
solenberg2100c0b2017-03-01 11:29:29 -08001056 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001057}
1058
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059// Test that bitrate cannot be set for CBR codecs.
1060// Bitrate is ignored if it is higher than the fixed bitrate.
1061// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001062TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001063 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001064
1065 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001066 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001067 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001068
1069 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001070 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001072
1073 send_parameters_.max_bandwidth_bps = 128;
1074 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001076}
1077
skvlade0d46372016-04-07 22:59:22 -07001078// Test that the per-stream bitrate limit and the global
1079// bitrate limit both apply.
1080TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1081 EXPECT_TRUE(SetupSendStream());
1082
ossu20a4b3f2017-04-27 02:08:52 -07001083 // opus, default bitrate == 32000.
1084 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001085 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1086 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1087 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1088
1089 // CBR codecs allow both maximums to exceed the bitrate.
1090 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1093 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1094
1095 // CBR codecs don't allow per stream maximums to be too low.
1096 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1097 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1098}
1099
1100// Test that an attempt to set RtpParameters for a stream that does not exist
1101// fails.
1102TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1103 EXPECT_TRUE(SetupChannel());
1104 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001105 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001106 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001107
1108 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001109 EXPECT_FALSE(
1110 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001111}
1112
1113TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001114 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001115 // This test verifies that setting RtpParameters succeeds only if
1116 // the structure contains exactly one encoding.
1117 // TODO(skvlad): Update this test when we start supporting setting parameters
1118 // for each encoding individually.
1119
1120 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001122 // Two or more encodings should result in failure.
1123 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001124 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001125 // Zero encodings should also fail.
1126 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001127 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001128}
1129
1130// Changing the SSRC through RtpParameters is not allowed.
1131TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1132 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001134 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001135 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001136}
1137
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001138// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001140TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1141 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001142 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001143 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001145 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146 ASSERT_EQ(1u, parameters.encodings.size());
1147 ASSERT_TRUE(parameters.encodings[0].active);
1148 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001149 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001150 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001151
1152 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001153 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001154 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001155 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001156 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001157 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001158}
1159
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160// Test that SetRtpSendParameters configures the correct encoding channel for
1161// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001162TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1163 SetupForMultiSendStream();
1164 // Create send streams.
1165 for (uint32_t ssrc : kSsrcs4) {
1166 EXPECT_TRUE(
1167 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1168 }
1169 // Configure one stream to be limited by the stream config, another to be
1170 // limited by the global max, and the third one with no per-stream limit
1171 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001172 SetGlobalMaxBitrate(kOpusCodec, 32000);
1173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1174 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001175 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1176
ossu20a4b3f2017-04-27 02:08:52 -07001177 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1178 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1179 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001180
1181 // Remove the global cap; the streams should switch to their respective
1182 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001183 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001184 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1185 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1186 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001187}
1188
Tim Haloun648d28a2018-10-18 16:52:22 -07001189// RTCRtpEncodingParameters.network_priority must be one of a few values
1190// derived from the default priority, corresponding to very-low, low, medium,
1191// or high.
1192TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1193 EXPECT_TRUE(SetupSendStream());
1194 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1195 EXPECT_EQ(1UL, parameters.encodings.size());
1196 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1197 parameters.encodings[0].network_priority);
1198
1199 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1200 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1201 for (auto it : good_values) {
1202 parameters.encodings[0].network_priority = it;
1203 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1204 }
1205 for (auto it : bad_values) {
1206 parameters.encodings[0].network_priority = it;
1207 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1208 }
1209}
1210
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001211// Test that GetRtpSendParameters returns the currently configured codecs.
1212TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001213 EXPECT_TRUE(SetupSendStream());
1214 cricket::AudioSendParameters parameters;
1215 parameters.codecs.push_back(kIsacCodec);
1216 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001217 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218
solenberg2100c0b2017-03-01 11:29:29 -08001219 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001220 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1222 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001223}
1224
Florent Castellidacec712018-05-24 16:24:21 +02001225// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1226TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1227 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1228 params.cname = "rtcpcname";
1229 EXPECT_TRUE(SetupSendStream(params));
1230
1231 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1232 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1233}
1234
Florent Castelliabe301f2018-06-12 18:33:49 +02001235TEST_F(WebRtcVoiceEngineTestFake,
1236 DetectRtpSendParameterHeaderExtensionsChange) {
1237 EXPECT_TRUE(SetupSendStream());
1238
1239 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1240 rtp_parameters.header_extensions.emplace_back();
1241
1242 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1243
1244 webrtc::RTCError result =
1245 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1246 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1247}
1248
deadbeefcb443432016-12-12 11:12:36 -08001249// Test that GetRtpSendParameters returns an SSRC.
1250TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1251 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001252 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001253 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001254 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001255}
1256
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001258TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001259 EXPECT_TRUE(SetupSendStream());
1260 cricket::AudioSendParameters parameters;
1261 parameters.codecs.push_back(kIsacCodec);
1262 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001263 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
solenberg2100c0b2017-03-01 11:29:29 -08001265 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001266
1267 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001268 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001269
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001270 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001271 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1272 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001273}
1274
minyuececec102017-03-27 13:04:25 -07001275// Test that max_bitrate_bps in send stream config gets updated correctly when
1276// SetRtpSendParameters is called.
1277TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1278 webrtc::test::ScopedFieldTrials override_field_trials(
1279 "WebRTC-Audio-SendSideBwe/Enabled/");
1280 EXPECT_TRUE(SetupSendStream());
1281 cricket::AudioSendParameters send_parameters;
1282 send_parameters.codecs.push_back(kOpusCodec);
1283 SetSendParameters(send_parameters);
1284
1285 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1286 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1287 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1288
1289 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001290 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001291 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001292
1293 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1294 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1295}
1296
Seth Hampson24722b32017-12-22 09:36:42 -08001297// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1298// a value <= 0, setting the parameters returns false.
1299TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1300 EXPECT_TRUE(SetupSendStream());
1301 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1302 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1303 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1304 rtp_parameters.encodings[0].bitrate_priority);
1305
1306 rtp_parameters.encodings[0].bitrate_priority = 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 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001309 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001310}
1311
1312// Test that the bitrate_priority in the send stream config gets updated when
1313// SetRtpSendParameters is set for the VoiceMediaChannel.
1314TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1315 EXPECT_TRUE(SetupSendStream());
1316 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1317
1318 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1319 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1320 rtp_parameters.encodings[0].bitrate_priority);
1321 double new_bitrate_priority = 2.0;
1322 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001323 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001324
1325 // The priority should get set for both the audio channel's rtp parameters
1326 // and the audio send stream's audio config.
1327 EXPECT_EQ(
1328 new_bitrate_priority,
1329 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1330 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1331}
1332
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001333// Test that GetRtpReceiveParameters returns the currently configured codecs.
1334TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1335 EXPECT_TRUE(SetupRecvStream());
1336 cricket::AudioRecvParameters parameters;
1337 parameters.codecs.push_back(kIsacCodec);
1338 parameters.codecs.push_back(kPcmuCodec);
1339 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1340
1341 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001342 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001343 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1344 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1345 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1346}
1347
deadbeefcb443432016-12-12 11:12:36 -08001348// Test that GetRtpReceiveParameters returns an SSRC.
1349TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1350 EXPECT_TRUE(SetupRecvStream());
1351 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001352 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001353 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001354 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001355}
1356
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001357// Test that if we set/get parameters multiple times, we get the same results.
1358TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1359 EXPECT_TRUE(SetupRecvStream());
1360 cricket::AudioRecvParameters parameters;
1361 parameters.codecs.push_back(kIsacCodec);
1362 parameters.codecs.push_back(kPcmuCodec);
1363 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1364
1365 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001366 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001367
1368 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001369 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001370
1371 // ... And this shouldn't change the params returned by
1372 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001373 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1374 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001375}
1376
deadbeef3bc15102017-04-20 19:25:07 -07001377// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1378// aren't signaled. It should return an empty "RtpEncodingParameters" when
1379// configured to receive an unsignaled stream and no packets have been received
1380// yet, and start returning the SSRC once a packet has been received.
1381TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1382 ASSERT_TRUE(SetupChannel());
1383 // Call necessary methods to configure receiving a default stream as
1384 // soon as it arrives.
1385 cricket::AudioRecvParameters parameters;
1386 parameters.codecs.push_back(kIsacCodec);
1387 parameters.codecs.push_back(kPcmuCodec);
1388 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1389
1390 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1391 // stream. Should return nothing.
1392 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1393
1394 // Set a sink for an unsignaled stream.
1395 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1396 // Value of "0" means "unsignaled stream".
1397 channel_->SetRawAudioSink(0, std::move(fake_sink));
1398
1399 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1400 // in this method means "unsignaled stream".
1401 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1402 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1403 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1404
1405 // Receive PCMU packet (SSRC=1).
1406 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1407
1408 // The |ssrc| member should still be unset.
1409 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1410 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1411 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1412}
1413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414// Test that we apply codecs properly.
1415TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001416 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 cricket::AudioSendParameters parameters;
1418 parameters.codecs.push_back(kIsacCodec);
1419 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001420 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001422 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1425 EXPECT_EQ(96, send_codec_spec.payload_type);
1426 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1427 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1428 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001429 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001430 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001431}
1432
ossu20a4b3f2017-04-27 02:08:52 -07001433// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1434// AudioSendStream.
1435TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 cricket::AudioSendParameters parameters;
1438 parameters.codecs.push_back(kIsacCodec);
1439 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001440 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 parameters.codecs[0].id = 96;
1442 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001443 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001446 // Calling SetSendCodec again with same codec which is already set.
1447 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001448 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001449 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001450}
1451
ossu20a4b3f2017-04-27 02:08:52 -07001452// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1453// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001454
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001455// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001457 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 cricket::AudioSendParameters parameters;
1459 parameters.codecs.push_back(kOpusCodec);
1460 parameters.codecs[0].bitrate = 0;
1461 parameters.codecs[0].clockrate = 50000;
1462 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001465// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 0;
1471 parameters.codecs[0].channels = 0;
1472 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001475// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001477 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001478 cricket::AudioSendParameters parameters;
1479 parameters.codecs.push_back(kOpusCodec);
1480 parameters.codecs[0].bitrate = 0;
1481 parameters.codecs[0].channels = 0;
1482 parameters.codecs[0].params["stereo"] = "1";
1483 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484}
1485
1486// Test that if channel is 1 for opus and there's no stereo, we fail.
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001488 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001489 cricket::AudioSendParameters parameters;
1490 parameters.codecs.push_back(kOpusCodec);
1491 parameters.codecs[0].bitrate = 0;
1492 parameters.codecs[0].channels = 1;
1493 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494}
1495
1496// Test that if channel is 1 for opus and stereo=0, we fail.
1497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].bitrate = 0;
1502 parameters.codecs[0].channels = 1;
1503 parameters.codecs[0].params["stereo"] = "0";
1504 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505}
1506
1507// Test that if channel is 1 for opus and stereo=1, we fail.
1508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].bitrate = 0;
1513 parameters.codecs[0].channels = 1;
1514 parameters.codecs[0].params["stereo"] = "1";
1515 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
ossu20a4b3f2017-04-27 02:08:52 -07001518// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 cricket::AudioSendParameters parameters;
1522 parameters.codecs.push_back(kOpusCodec);
1523 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001525 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001526}
1527
ossu20a4b3f2017-04-27 02:08:52 -07001528// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001530 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 cricket::AudioSendParameters parameters;
1532 parameters.codecs.push_back(kOpusCodec);
1533 parameters.codecs[0].bitrate = 0;
1534 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001535 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001536 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001537}
1538
ossu20a4b3f2017-04-27 02:08:52 -07001539// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001540TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001541 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001542 cricket::AudioSendParameters parameters;
1543 parameters.codecs.push_back(kOpusCodec);
1544 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001545 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001547 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001548 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001549
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001551 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001552 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001553}
1554
ossu20a4b3f2017-04-27 02:08:52 -07001555// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001557 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 cricket::AudioSendParameters parameters;
1559 parameters.codecs.push_back(kOpusCodec);
1560 parameters.codecs[0].bitrate = 0;
1561 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001563 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
ossu20a4b3f2017-04-27 02:08:52 -07001566// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kOpusCodec);
1571 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001572 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001575 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001576
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001579 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001580}
1581
ossu20a4b3f2017-04-27 02:08:52 -07001582// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001584 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001588 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001589 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1590 EXPECT_EQ(111, spec.payload_type);
1591 EXPECT_EQ(96000, spec.target_bitrate_bps);
1592 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001593 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001594 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595}
1596
ossu20a4b3f2017-04-27 02:08:52 -07001597// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kOpusCodec);
1602 parameters.codecs[0].bitrate = 30000;
1603 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001605 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606}
1607
ossu20a4b3f2017-04-27 02:08:52 -07001608// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001609TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001610 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001611 cricket::AudioSendParameters parameters;
1612 parameters.codecs.push_back(kOpusCodec);
1613 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001614 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001615 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616}
1617
ossu20a4b3f2017-04-27 02:08:52 -07001618// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001620 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001621 cricket::AudioSendParameters parameters;
1622 parameters.codecs.push_back(kOpusCodec);
1623 parameters.codecs[0].bitrate = 30000;
1624 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001626 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001627}
1628
stefan13f1a0a2016-11-30 07:22:58 -08001629TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1630 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1631 200000);
1632}
1633
1634TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1635 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1636}
1637
1638TEST_F(WebRtcVoiceEngineTestFake,
1639 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1640 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1641}
1642
1643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1644 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1645}
1646
Yves Gerey665174f2018-06-19 15:03:05 +02001647TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001648 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1649 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001650 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001651 // Setting max bitrate should keep previous min bitrate
1652 // Setting max bitrate should not reset start bitrate.
1653 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1654 SetSdpBitrateParameters(
1655 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1656 Field(&BitrateConstraints::start_bitrate_bps, -1),
1657 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001658 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001659}
1660
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001661// Test that we can enable NACK with opus as callee.
1662TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001663 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 cricket::AudioSendParameters parameters;
1665 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001666 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1667 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001668 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001669 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001670 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001671 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001672
Yves Gerey665174f2018-06-19 15:03:05 +02001673 EXPECT_TRUE(
1674 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001675}
1676
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677// Test that we can enable NACK on receive streams.
1678TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001679 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 cricket::AudioSendParameters parameters;
1682 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001683 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1684 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001685 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001687 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688}
1689
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690// Test that we can disable NACK on receive streams.
1691TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001692 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 cricket::AudioSendParameters parameters;
1695 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001696 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1697 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001701 parameters.codecs.clear();
1702 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001704 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705}
1706
1707// Test that NACK is enabled on a new receive stream.
1708TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001709 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 cricket::AudioSendParameters parameters;
1711 parameters.codecs.push_back(kIsacCodec);
1712 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001713 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1714 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716
solenberg2100c0b2017-03-01 11:29:29 -08001717 EXPECT_TRUE(AddRecvStream(kSsrcY));
1718 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1719 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1720 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721}
1722
stefanba4c0e42016-02-04 04:12:24 -08001723TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001725 cricket::AudioSendParameters send_parameters;
1726 send_parameters.codecs.push_back(kOpusCodec);
1727 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001729
1730 cricket::AudioRecvParameters recv_parameters;
1731 recv_parameters.codecs.push_back(kIsacCodec);
1732 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001733 EXPECT_TRUE(AddRecvStream(kSsrcX));
1734 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001735 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001736 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001737
ossudedfd282016-06-14 07:12:39 -07001738 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001740 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001741 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001742 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001743}
1744
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001745// Test that we can switch back and forth between Opus and ISAC with CN.
1746TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001747 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001748
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters opus_parameters;
1750 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001752 {
ossu20a4b3f2017-04-27 02:08:52 -07001753 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1754 EXPECT_EQ(111, spec.payload_type);
1755 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001756 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 cricket::AudioSendParameters isac_parameters;
1759 isac_parameters.codecs.push_back(kIsacCodec);
1760 isac_parameters.codecs.push_back(kCn16000Codec);
1761 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(103, spec.payload_type);
1766 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001767 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001770 {
ossu20a4b3f2017-04-27 02:08:52 -07001771 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1772 EXPECT_EQ(111, spec.payload_type);
1773 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001774 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775}
1776
1777// Test that we handle various ways of specifying bitrate.
1778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001779 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001780 cricket::AudioSendParameters parameters;
1781 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001783 {
ossu20a4b3f2017-04-27 02:08:52 -07001784 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1785 EXPECT_EQ(103, spec.payload_type);
1786 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1787 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001788 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789
Yves Gerey665174f2018-06-19 15:03:05 +02001790 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 {
ossu20a4b3f2017-04-27 02:08:52 -07001793 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1794 EXPECT_EQ(103, spec.payload_type);
1795 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1796 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001797 }
Yves Gerey665174f2018-06-19 15:03:05 +02001798 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001799 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001800 {
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(103, spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1804 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001805 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806
Yves Gerey665174f2018-06-19 15:03:05 +02001807 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001808 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001809 {
ossu20a4b3f2017-04-27 02:08:52 -07001810 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1811 EXPECT_EQ(0, spec.payload_type);
1812 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1813 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001814 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815
Yves Gerey665174f2018-06-19 15:03:05 +02001816 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001818 {
ossu20a4b3f2017-04-27 02:08:52 -07001819 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1820 EXPECT_EQ(0, spec.payload_type);
1821 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1822 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001823 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001826 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001827 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001828 {
ossu20a4b3f2017-04-27 02:08:52 -07001829 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1830 EXPECT_EQ(111, spec.payload_type);
1831 EXPECT_STREQ("opus", spec.format.name.c_str());
1832 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001833 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001834}
1835
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001836// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
1840 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001841}
1842
1843// Test that we can set send codecs even with telephone-event codec as the first
1844// one on the list.
1845TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001846 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001848 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001849 parameters.codecs.push_back(kIsacCodec);
1850 parameters.codecs.push_back(kPcmuCodec);
1851 parameters.codecs[0].id = 98; // DTMF
1852 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001854 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1855 EXPECT_EQ(96, spec.payload_type);
1856 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001857 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001858 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001859}
1860
Harald Alvestranda1f66612018-02-21 11:24:23 +01001861// Test that CanInsertDtmf() is governed by the send flag
1862TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1863 EXPECT_TRUE(SetupSendStream());
1864 cricket::AudioSendParameters parameters;
1865 parameters.codecs.push_back(kTelephoneEventCodec1);
1866 parameters.codecs.push_back(kPcmuCodec);
1867 parameters.codecs[0].id = 98; // DTMF
1868 parameters.codecs[1].id = 96;
1869 SetSendParameters(parameters);
1870 EXPECT_FALSE(channel_->CanInsertDtmf());
1871 SetSend(true);
1872 EXPECT_TRUE(channel_->CanInsertDtmf());
1873 SetSend(false);
1874 EXPECT_FALSE(channel_->CanInsertDtmf());
1875}
1876
solenberg31642aa2016-03-14 08:00:37 -07001877// Test that payload type range is limited for telephone-event codec.
1878TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001879 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001880 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001881 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs[0].id = 0; // DTMF
1884 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001885 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001886 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001887 EXPECT_TRUE(channel_->CanInsertDtmf());
1888 parameters.codecs[0].id = 128; // DTMF
1889 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1890 EXPECT_FALSE(channel_->CanInsertDtmf());
1891 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001893 EXPECT_TRUE(channel_->CanInsertDtmf());
1894 parameters.codecs[0].id = -1; // DTMF
1895 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1896 EXPECT_FALSE(channel_->CanInsertDtmf());
1897}
1898
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001899// Test that we can set send codecs even with CN codec as the first
1900// one on the list.
1901TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001902 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001903 cricket::AudioSendParameters parameters;
1904 parameters.codecs.push_back(kCn16000Codec);
1905 parameters.codecs.push_back(kIsacCodec);
1906 parameters.codecs.push_back(kPcmuCodec);
1907 parameters.codecs[0].id = 98; // wideband CN
1908 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001909 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001910 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1911 EXPECT_EQ(96, send_codec_spec.payload_type);
1912 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001913 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001914}
1915
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001916// Test that we set VAD and DTMF types correctly as caller.
1917TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001918 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001919 cricket::AudioSendParameters parameters;
1920 parameters.codecs.push_back(kIsacCodec);
1921 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001922 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 parameters.codecs.push_back(kCn16000Codec);
1924 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001925 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001926 parameters.codecs[0].id = 96;
1927 parameters.codecs[2].id = 97; // wideband CN
1928 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001929 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001930 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1931 EXPECT_EQ(96, send_codec_spec.payload_type);
1932 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001933 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001934 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001935 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001936 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937}
1938
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001939// Test that we set VAD and DTMF types correctly as callee.
1940TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001941 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001942 cricket::AudioSendParameters parameters;
1943 parameters.codecs.push_back(kIsacCodec);
1944 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001945 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001946 parameters.codecs.push_back(kCn16000Codec);
1947 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001948 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[0].id = 96;
1950 parameters.codecs[2].id = 97; // wideband CN
1951 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001952 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001953 EXPECT_TRUE(
1954 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001955
ossu20a4b3f2017-04-27 02:08:52 -07001956 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1957 EXPECT_EQ(96, send_codec_spec.payload_type);
1958 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001959 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001960 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001961 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001962 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001963}
1964
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965// Test that we only apply VAD if we have a CN codec that matches the
1966// send codec clockrate.
1967TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001968 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001970 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001971 parameters.codecs.push_back(kIsacCodec);
1972 parameters.codecs.push_back(kCn16000Codec);
1973 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001974 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001975 {
ossu20a4b3f2017-04-27 02:08:52 -07001976 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1977 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001978 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001979 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001980 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001981 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001984 {
ossu20a4b3f2017-04-27 02:08:52 -07001985 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1986 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001987 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001988 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001989 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001992 {
ossu20a4b3f2017-04-27 02:08:52 -07001993 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1994 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001995 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001996 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001997 }
Brave Yao5225dd82015-03-26 07:39:19 +08001998 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002001 {
ossu20a4b3f2017-04-27 02:08:52 -07002002 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2003 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002004 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002005 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002006}
2007
2008// Test that we perform case-insensitive matching of codec names.
2009TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002010 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 cricket::AudioSendParameters parameters;
2012 parameters.codecs.push_back(kIsacCodec);
2013 parameters.codecs.push_back(kPcmuCodec);
2014 parameters.codecs.push_back(kCn16000Codec);
2015 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002016 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002017 parameters.codecs[0].name = "iSaC";
2018 parameters.codecs[0].id = 96;
2019 parameters.codecs[2].id = 97; // wideband CN
2020 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002021 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002022 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2023 EXPECT_EQ(96, send_codec_spec.payload_type);
2024 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002025 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002026 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002027 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002028 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002029}
2030
stefanba4c0e42016-02-04 04:12:24 -08002031class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2032 public:
2033 WebRtcVoiceEngineWithSendSideBweTest()
2034 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2035};
2036
2037TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2038 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002039 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2040 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002041 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002042 "uri", &RtpExtension::uri,
2043 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002044}
2045
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002046// Test support for audio level header extension.
2047TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002048 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002049}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002051 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002052}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002053
solenbergd4adce42016-11-17 06:26:52 -08002054// Test support for transport sequence number header extension.
2055TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2056 TestSetSendRtpHeaderExtensions(
2057 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002058}
solenbergd4adce42016-11-17 06:26:52 -08002059TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2060 TestSetRecvRtpHeaderExtensions(
2061 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002062}
2063
solenberg1ac56142015-10-13 03:58:19 -07002064// Test that we can create a channel and start sending on it.
2065TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002066 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(send_parameters_);
2068 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002070 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002072}
2073
2074// Test that a channel will send if and only if it has a source and is enabled
2075// for sending.
2076TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002078 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002079 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002080 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2082 SetAudioSend(kSsrcX, true, &fake_source_);
2083 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2084 SetAudioSend(kSsrcX, true, nullptr);
2085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002086}
2087
solenberg94218532016-06-16 10:53:22 -07002088// Test that a channel is muted/unmuted.
2089TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2090 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002091 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002092 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2093 SetAudioSend(kSsrcX, true, nullptr);
2094 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2095 SetAudioSend(kSsrcX, false, nullptr);
2096 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002097}
2098
solenberg6d6e7c52016-04-13 09:07:30 -07002099// Test that SetSendParameters() does not alter a stream's send state.
2100TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2101 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002102 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002103
2104 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002105 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002106 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002107
2108 // Changing RTP header extensions will recreate the AudioSendStream.
2109 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002110 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002111 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002113
2114 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002115 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002117
2118 // Changing RTP header extensions will recreate the AudioSendStream.
2119 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002121 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002122}
2123
solenberg1ac56142015-10-13 03:58:19 -07002124// Test that we can create a channel and start playing out on it.
2125TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002126 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002127 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002128 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002130 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002131 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132}
2133
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134// Test that we can add and remove send streams.
2135TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2136 SetupForMultiSendStream();
2137
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002139 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140
solenbergc96df772015-10-21 13:01:53 -07002141 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002142 EXPECT_TRUE(
2143 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002144 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002146 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147 }
tfarina5237aaf2015-11-10 23:44:30 -08002148 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149
solenbergc96df772015-10-21 13:01:53 -07002150 // Delete the send streams.
2151 for (uint32_t ssrc : kSsrcs4) {
2152 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002153 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002154 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 }
solenbergc96df772015-10-21 13:01:53 -07002156 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157}
2158
2159// Test SetSendCodecs correctly configure the codecs in all send streams.
2160TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2161 SetupForMultiSendStream();
2162
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002164 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002165 EXPECT_TRUE(
2166 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002167 }
2168
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002171 parameters.codecs.push_back(kIsacCodec);
2172 parameters.codecs.push_back(kCn16000Codec);
2173 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002174 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175
2176 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002177 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002178 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2179 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002180 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2181 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002182 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002183 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002184 }
2185
minyue7a973442016-10-20 03:27:12 -07002186 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002187 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002188 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002189 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002190 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2191 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002192 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2193 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002194 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195 }
2196}
2197
2198// Test we can SetSend on all send streams correctly.
2199TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2200 SetupForMultiSendStream();
2201
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002203 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002204 EXPECT_TRUE(
2205 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002206 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002207 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 }
2209
2210 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002211 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002212 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002214 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 }
2216
2217 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002218 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002219 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002221 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002222 }
2223}
2224
2225// Test we can set the correct statistics on all send streams.
2226TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2227 SetupForMultiSendStream();
2228
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002229 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002230 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002231 EXPECT_TRUE(
2232 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002233 }
solenberg85a04962015-10-27 03:35:21 -07002234
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002235 // Create a receive stream to check that none of the send streams end up in
2236 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002238
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002239 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002240 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002241 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002242 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002243
solenberg85a04962015-10-27 03:35:21 -07002244 // Check stats for the added streams.
2245 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002246 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002247 cricket::VoiceMediaInfo info;
2248 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002249
solenberg85a04962015-10-27 03:35:21 -07002250 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002251 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002252 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002253 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002254 }
hbos1acfbd22016-11-17 23:43:29 -08002255 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002256
2257 // We have added one receive stream. We should see empty stats.
2258 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002259 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002260 }
solenberg1ac56142015-10-13 03:58:19 -07002261
solenberg2100c0b2017-03-01 11:29:29 -08002262 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002263 {
2264 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002265 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002266 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002267 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002268 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002269 EXPECT_EQ(0u, info.receivers.size());
2270 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002271
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002272 // Deliver a new packet - a default receive stream should be created and we
2273 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002274 {
2275 cricket::VoiceMediaInfo info;
2276 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2277 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002278 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002279 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002280 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002281 EXPECT_EQ(1u, info.receivers.size());
2282 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002283 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002284 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002285}
2286
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002287// Test that we can add and remove receive streams, and do proper send/playout.
2288// We can receive on multiple streams while sending one stream.
2289TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002290 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291
solenberg1ac56142015-10-13 03:58:19 -07002292 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002293 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002294 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
solenberg1ac56142015-10-13 03:58:19 -07002296 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002298 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300
solenberg1ac56142015-10-13 03:58:19 -07002301 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002302 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
2304 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002305 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2306 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2307 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002308
2309 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002310 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002311 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312
2313 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002314 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2316 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
aleloi84ef6152016-08-04 05:28:21 -07002318 // Restart playout and make sure recv streams are played out.
2319 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002320 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2321 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002322
aleloi84ef6152016-08-04 05:28:21 -07002323 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002324 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2325 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002326}
2327
wu@webrtc.org97077a32013-10-25 21:18:33 +00002328TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002329 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002330 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002331 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002332 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002333 const auto& agc_config = apm_config_.gain_controller1;
2334
2335 // Ensure default options.
2336 VerifyGainControlEnabledCorrectly();
2337 VerifyGainControlDefaultSettings();
2338
2339 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002340 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002341 EXPECT_FALSE(agc_config.enabled);
2342 send_parameters_.options.auto_gain_control = absl::nullopt;
2343
2344 send_parameters_.options.tx_agc_target_dbov = 5;
2345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(5, agc_config.target_level_dbfs);
2347 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2348
2349 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2350 SetSendParameters(send_parameters_);
2351 EXPECT_EQ(10, agc_config.compression_gain_db);
2352 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2353
2354 send_parameters_.options.tx_agc_limiter = false;
2355 SetSendParameters(send_parameters_);
2356 EXPECT_FALSE(agc_config.enable_limiter);
2357 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2358
2359 SetSendParameters(send_parameters_);
2360 // Expect all options to have been preserved.
2361 EXPECT_FALSE(agc_config.enabled);
2362 EXPECT_EQ(5, agc_config.target_level_dbfs);
2363 EXPECT_EQ(10, agc_config.compression_gain_db);
2364 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002365}
2366
minyue6b825df2016-10-31 04:08:32 -07002367TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2368 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002369 send_parameters_.options.audio_network_adaptor = true;
2370 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002371 SetSendParameters(send_parameters_);
2372 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002373 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002374}
2375
2376TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2377 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002378 send_parameters_.options.audio_network_adaptor = true;
2379 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002380 SetSendParameters(send_parameters_);
2381 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002382 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002383 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002384 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002385 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002386 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002387}
2388
2389TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2390 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002391 send_parameters_.options.audio_network_adaptor = true;
2392 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002393 SetSendParameters(send_parameters_);
2394 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002395 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002396 const int initial_num = call_.GetNumCreatedSendStreams();
2397 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002398 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002399 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2400 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002401 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002402 // AudioSendStream not expected to be recreated.
2403 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2404 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002405 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002406}
2407
michaelt6672b262017-01-11 10:17:59 -08002408class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2409 : public WebRtcVoiceEngineTestFake {
2410 public:
2411 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2412 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002413 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2414 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002415 "Enabled/") {}
2416};
2417
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002419// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002421 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002422 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423}
2424
2425TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2426 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002427 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002428 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002429 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002430 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002431 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002432 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002433 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434
solenberg85a04962015-10-27 03:35:21 -07002435 // Check stats for the added streams.
2436 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002437 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002438 cricket::VoiceMediaInfo info;
2439 EXPECT_EQ(true, channel_->GetStats(&info));
2440
2441 // We have added one send stream. We should see the stats we've set.
2442 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002443 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002444 // We have added one receive stream. We should see empty stats.
2445 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002446 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002447 }
solenberg1ac56142015-10-13 03:58:19 -07002448
solenberg566ef242015-11-06 15:34:49 -08002449 // Start sending - this affects some reported stats.
2450 {
2451 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002452 SetSend(true);
Alex Narestbbeb1092019-08-16 11:49:04 +02002453 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg566ef242015-11-06 15:34:49 -08002454 EXPECT_EQ(true, channel_->GetStats(&info));
2455 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002456 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002457 }
2458
solenberg2100c0b2017-03-01 11:29:29 -08002459 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002460 {
2461 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002462 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002463 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002464 EXPECT_EQ(true, channel_->GetStats(&info));
2465 EXPECT_EQ(1u, info.senders.size());
2466 EXPECT_EQ(0u, info.receivers.size());
2467 }
solenberg1ac56142015-10-13 03:58:19 -07002468
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002469 // Deliver a new packet - a default receive stream should be created and we
2470 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002471 {
2472 cricket::VoiceMediaInfo info;
2473 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2474 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002475 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002476 EXPECT_EQ(true, channel_->GetStats(&info));
2477 EXPECT_EQ(1u, info.senders.size());
2478 EXPECT_EQ(1u, info.receivers.size());
2479 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002480 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002481 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482}
2483
2484// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002485// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2489 EXPECT_TRUE(AddRecvStream(kSsrcY));
2490 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491}
2492
2493// Test that the local SSRC is the same on sending and receiving channels if the
2494// receive channel is created before the send channel.
2495TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002496 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002497 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002498 EXPECT_TRUE(
2499 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002500 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2501 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502}
2503
2504// Test that we can properly receive packets.
2505TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002507 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002509
Yves Gerey665174f2018-06-19 15:03:05 +02002510 EXPECT_TRUE(
2511 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512}
2513
2514// Test that we can properly receive packets on multiple streams.
2515TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002516 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002517 const uint32_t ssrc1 = 1;
2518 const uint32_t ssrc2 = 2;
2519 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002520 EXPECT_TRUE(AddRecvStream(ssrc1));
2521 EXPECT_TRUE(AddRecvStream(ssrc2));
2522 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002524 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002525 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002527 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528 }
mflodman3d7db262016-04-29 00:57:13 -07002529
2530 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2531 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2532 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2533
2534 EXPECT_EQ(s1.received_packets(), 0);
2535 EXPECT_EQ(s2.received_packets(), 0);
2536 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002537
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(s1.received_packets(), 0);
2540 EXPECT_EQ(s2.received_packets(), 0);
2541 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002542
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002544 EXPECT_EQ(s1.received_packets(), 1);
2545 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2546 EXPECT_EQ(s2.received_packets(), 0);
2547 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002548
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002549 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002550 EXPECT_EQ(s1.received_packets(), 1);
2551 EXPECT_EQ(s2.received_packets(), 1);
2552 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2553 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002554
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002556 EXPECT_EQ(s1.received_packets(), 1);
2557 EXPECT_EQ(s2.received_packets(), 1);
2558 EXPECT_EQ(s3.received_packets(), 1);
2559 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002560
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2562 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2563 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564}
2565
solenberg2100c0b2017-03-01 11:29:29 -08002566// Test that receiving on an unsignaled stream works (a stream is created).
2567TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002568 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002569 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002570
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002572
Mirko Bonadeif859e552018-05-30 15:31:29 +02002573 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002574 EXPECT_TRUE(
2575 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002576}
2577
Seth Hampson5897a6e2018-04-03 11:16:33 -07002578// Tests that when we add a stream without SSRCs, but contains a stream_id
2579// that it is stored and its stream id is later used when the first packet
2580// arrives to properly create a receive stream with a sync label.
2581TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2582 const char kSyncLabel[] = "sync_label";
2583 EXPECT_TRUE(SetupChannel());
2584 cricket::StreamParams unsignaled_stream;
2585 unsignaled_stream.set_stream_ids({kSyncLabel});
2586 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2587 // The stream shouldn't have been created at this point because it doesn't
2588 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002589 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002590
2591 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2592
Mirko Bonadeif859e552018-05-30 15:31:29 +02002593 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002594 EXPECT_TRUE(
2595 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2596 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2597
2598 // Removing the unsignaled stream clears the cached parameters. If a new
2599 // default unsignaled receive stream is created it will not have a sync group.
2600 channel_->RemoveRecvStream(0);
2601 channel_->RemoveRecvStream(kSsrc1);
2602
2603 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2604
Mirko Bonadeif859e552018-05-30 15:31:29 +02002605 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002606 EXPECT_TRUE(
2607 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2608 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2609}
2610
solenberg2100c0b2017-03-01 11:29:29 -08002611// Test that receiving N unsignaled stream works (streams will be created), and
2612// that packets are forwarded to them all.
2613TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002614 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002615 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002616 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2617
solenberg2100c0b2017-03-01 11:29:29 -08002618 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002619 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002620 rtc::SetBE32(&packet[8], ssrc);
2621 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002622
solenberg2100c0b2017-03-01 11:29:29 -08002623 // Verify we have one new stream for each loop iteration.
2624 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002625 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2626 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002627 }
mflodman3d7db262016-04-29 00:57:13 -07002628
solenberg2100c0b2017-03-01 11:29:29 -08002629 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002630 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002631 rtc::SetBE32(&packet[8], ssrc);
2632 DeliverPacket(packet, sizeof(packet));
2633
solenbergebb349d2017-03-13 05:46:15 -07002634 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002635 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2636 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2637 }
2638
2639 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2640 constexpr uint32_t kAnotherSsrc = 667;
2641 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002642 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002643
2644 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002645 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002646 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002647 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002648 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2649 EXPECT_EQ(2, streams[i]->received_packets());
2650 }
2651 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2652 EXPECT_EQ(1, streams[i]->received_packets());
2653 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002654 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002655}
2656
solenberg2100c0b2017-03-01 11:29:29 -08002657// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002658// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002659TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002660 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002661 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002662 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2663
2664 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002665 const uint32_t signaled_ssrc = 1;
2666 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002667 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002668 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002669 EXPECT_TRUE(
2670 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002671 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002672
2673 // Note that the first unknown SSRC cannot be 0, because we only support
2674 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002675 const uint32_t unsignaled_ssrc = 7011;
2676 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002677 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002678 EXPECT_TRUE(
2679 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002680 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002681
2682 DeliverPacket(packet, sizeof(packet));
2683 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2684
2685 rtc::SetBE32(&packet[8], signaled_ssrc);
2686 DeliverPacket(packet, sizeof(packet));
2687 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002688 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002689}
2690
solenberg4904fb62017-02-17 12:01:14 -08002691// Two tests to verify that adding a receive stream with the same SSRC as a
2692// previously added unsignaled stream will only recreate underlying stream
2693// objects if the stream parameters have changed.
2694TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2695 EXPECT_TRUE(SetupChannel());
2696
2697 // Spawn unsignaled stream with SSRC=1.
2698 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002699 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002700 EXPECT_TRUE(
2701 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002702
2703 // Verify that the underlying stream object in Call is not recreated when a
2704 // stream with SSRC=1 is added.
2705 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002706 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002707 int audio_receive_stream_id = streams.front()->id();
2708 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002709 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002710 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2711}
2712
2713TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2714 EXPECT_TRUE(SetupChannel());
2715
2716 // Spawn unsignaled stream with SSRC=1.
2717 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002718 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002719 EXPECT_TRUE(
2720 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002721
2722 // Verify that the underlying stream object in Call *is* recreated when a
2723 // stream with SSRC=1 is added, and which has changed stream parameters.
2724 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002725 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002726 int audio_receive_stream_id = streams.front()->id();
2727 cricket::StreamParams stream_params;
2728 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002729 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002730 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002731 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002732 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2733}
2734
solenberg1ac56142015-10-13 03:58:19 -07002735// Test that AddRecvStream creates new stream.
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002738 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739}
2740
2741// Test that after adding a recv stream, we do not decode more codecs than
2742// those previously passed into SetRecvCodecs.
2743TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002744 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002745 cricket::AudioRecvParameters parameters;
2746 parameters.codecs.push_back(kIsacCodec);
2747 parameters.codecs.push_back(kPcmuCodec);
2748 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002749 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002750 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2751 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2752 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753}
2754
2755// Test that we properly clean up any streams that were added, even if
2756// not explicitly removed.
2757TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002758 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002759 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(1));
2761 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002762
Mirko Bonadeif859e552018-05-30 15:31:29 +02002763 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2764 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765 delete channel_;
2766 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002767 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2768 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769}
2770
wu@webrtc.org78187522013-10-07 23:32:02 +00002771TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002773 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002774}
2775
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002776TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002777 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002778 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002779 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002780}
2781
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002782// Test the InsertDtmf on default send stream as caller.
2783TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002784 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785}
2786
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002787// Test the InsertDtmf on default send stream as callee
2788TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002789 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002790}
2791
2792// Test the InsertDtmf on specified send stream as caller.
2793TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002794 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002795}
2796
2797// Test the InsertDtmf on specified send stream as callee.
2798TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002799 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800}
2801
Johannes Kron9190b822018-10-29 11:22:05 +01002802// Test propagation of extmap allow mixed setting.
2803TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2804 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2805}
2806TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2807 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2808}
2809TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2810 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2811}
2812TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2813 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2814}
2815
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002817 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002818 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002819 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002820 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002821 .WillRepeatedly(Return(false));
2822 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2823 .Times(4)
2824 .WillRepeatedly(Return(false));
2825 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2826 .Times(2)
2827 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002828
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
solenberg246b8172015-12-08 09:50:23 -08002832 // Nothing set in AudioOptions, so everything should be as default.
2833 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002834 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002835 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002836 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002837 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002838 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002839 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840
Sam Zackrissonba502232019-01-04 10:36:48 +01002841 // Turn typing detection off.
2842 send_parameters_.options.typing_detection = false;
2843 SetSendParameters(send_parameters_);
2844 EXPECT_FALSE(IsTypingDetectionEnabled());
2845
2846 // Leave typing detection unchanged, but non-default.
2847 send_parameters_.options.typing_detection = absl::nullopt;
2848 SetSendParameters(send_parameters_);
2849 EXPECT_FALSE(IsTypingDetectionEnabled());
2850
2851 // Turn typing detection on.
2852 send_parameters_.options.typing_detection = true;
2853 SetSendParameters(send_parameters_);
2854 EXPECT_TRUE(IsTypingDetectionEnabled());
2855
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002857 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002858 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002859 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860
2861 // Turn echo cancellation back on, with settings, and make sure
2862 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002863 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002864 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002865 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002867 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002868 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002869 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002870 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002871
Per Åhgrenf40a3402019-04-25 08:50:11 +02002872 // Restore AEC to be on to work with the following tests.
2873 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002874 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002875
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002876 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002877 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002878 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002879 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002880 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
2882 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002883 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002884 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002885 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002886 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002887
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002888 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002889 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002891 send_parameters_.options.noise_suppression = false;
2892 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002894 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002895 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002896 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002897 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
solenberg1ac56142015-10-13 03:58:19 -07002899 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002900 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002903 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002904 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905}
2906
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002908 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002909 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2910 .Times(8)
2911 .WillRepeatedly(Return(false));
2912 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2913 .Times(8)
2914 .WillRepeatedly(Return(false));
2915 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2916 .Times(8)
2917 .WillRepeatedly(Return(false));
2918 EXPECT_CALL(adm_, RecordingIsInitialized())
2919 .Times(2)
2920 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002921 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2922 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002923 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002924
kwiberg686a8ef2016-02-26 03:00:35 -08002925 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002926 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2927 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2928 cricket::AudioOptions(),
2929 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002930 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002931 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2932 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2933 cricket::AudioOptions(),
2934 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935
2936 // Have to add a stream to make SetSend work.
2937 cricket::StreamParams stream1;
2938 stream1.ssrcs.push_back(1);
2939 channel1->AddSendStream(stream1);
2940 cricket::StreamParams stream2;
2941 stream2.ssrcs.push_back(2);
2942 channel2->AddSendStream(stream2);
2943
2944 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002946 parameters_options_all.options.echo_cancellation = true;
2947 parameters_options_all.options.auto_gain_control = true;
2948 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002949 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002950 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002951 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002952 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002953 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002954 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002955 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002956 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002957 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002958 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959
2960 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002961 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002962 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002963 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002964 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002965 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002966 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002967 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002968 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002969 expected_options.echo_cancellation = true;
2970 expected_options.auto_gain_control = true;
2971 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002972 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002973
2974 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002975 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002976 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002977 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002978 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002979 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002980 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002981 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002982 expected_options.echo_cancellation = true;
2983 expected_options.auto_gain_control = false;
2984 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002985 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002987 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002988 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002989 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002990 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002991 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002993 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002994 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002995 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002996 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002997 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002999 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003000 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003001 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003002 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003003 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3007 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003008 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3009 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003010 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003011 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003012 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003013 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003014 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003015 expected_options.echo_cancellation = true;
3016 expected_options.auto_gain_control = false;
3017 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003018 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019}
3020
wu@webrtc.orgde305012013-10-31 15:40:38 +00003021// This test verifies DSCP settings are properly applied on voice media channel.
3022TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003023 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003024 cricket::FakeNetworkInterface network_interface;
3025 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003026 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003027 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003028
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003029 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003030
Sebastian Jansson84848f22018-11-16 10:40:36 +01003031 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3032 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3033 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003034 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003035 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3036 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3037
3038 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003039 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3040 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3041 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003042 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003043 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3044
3045 // Create a send stream to configure
3046 EXPECT_TRUE(
3047 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3048 parameters = channel->GetRtpSendParameters(kSsrcZ);
3049 ASSERT_FALSE(parameters.encodings.empty());
3050
3051 // Various priorities map to various dscp values.
3052 parameters.encodings[0].network_priority = 4.0;
3053 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003054 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003055 parameters.encodings[0].network_priority = 0.5;
3056 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3057 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3058
3059 // A bad priority does not change the dscp value.
3060 parameters.encodings[0].network_priority = 0.0;
3061 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3062 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003063
Tim Haloun6ca98362018-09-17 17:06:08 -07003064 // Packets should also self-identify their dscp in PacketOptions.
3065 const uint8_t kData[10] = {0};
3066 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003067 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003068
nisse51542be2016-02-12 02:27:06 -08003069 // Verify that setting the option to false resets the
3070 // DiffServCodePoint.
3071 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003072 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3073 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3074 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003075 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003076 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3077 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3078
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003079 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003080}
3081
solenberg4bac9c52015-10-09 02:32:53 -07003082TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003083 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003084 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003085 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003086 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003087 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003088 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3089 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3090 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003091}
3092
solenberg2100c0b2017-03-01 11:29:29 -08003093TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003095
3096 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003097 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003098 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3099
3100 // Should remember the volume "2" which will be set on new unsignaled streams,
3101 // and also set the gain to 2 on existing unsignaled streams.
3102 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3103 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3104
3105 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3106 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3107 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3108 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3109 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3110 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3111
3112 // Setting gain with SSRC=0 should affect all unsignaled streams.
3113 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003114 if (kMaxUnsignaledRecvStreams > 1) {
3115 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3116 }
solenberg2100c0b2017-03-01 11:29:29 -08003117 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3118
3119 // Setting gain on an individual stream affects only that.
3120 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003121 if (kMaxUnsignaledRecvStreams > 1) {
3122 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3123 }
solenberg2100c0b2017-03-01 11:29:29 -08003124 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003125}
3126
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003127TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3128 EXPECT_TRUE(SetupChannel());
3129 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3130 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3131
3132 cricket::StreamParams stream;
3133 stream.ssrcs.push_back(kSsrcY);
3134 EXPECT_TRUE(channel_->AddRecvStream(stream));
3135 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3136 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3137 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3138}
3139
3140TEST_F(WebRtcVoiceEngineTestFake,
3141 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3142 // Here base minimum delay is abbreviated to delay in comments for shortness.
3143 EXPECT_TRUE(SetupChannel());
3144
3145 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3146 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3147 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3148 // Check that it doesn't provide default values for unknown ssrc.
3149 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3150
3151 // Check that default value for unsignaled streams is 0.
3152 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3153
3154 // Should remember the delay 100 which will be set on new unsignaled streams,
3155 // and also set the delay to 100 on existing unsignaled streams.
3156 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3157 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3158 // Check that it doesn't provide default values for unknown ssrc.
3159 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3160
3161 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3162 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3163 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3164 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3165 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3166 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3167
3168 // Setting delay with SSRC=0 should affect all unsignaled streams.
3169 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3170 if (kMaxUnsignaledRecvStreams > 1) {
3171 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3172 }
3173 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3174
3175 // Setting delay on an individual stream affects only that.
3176 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3177 if (kMaxUnsignaledRecvStreams > 1) {
3178 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3179 }
3180 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3181 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3182 // Check that it doesn't provide default values for unknown ssrc.
3183 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3184}
3185
Seth Hampson845e8782018-03-02 11:34:10 -08003186TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003187 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003188 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003189
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003191 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003192 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003193 // Creating two channels to make sure that sync label is set properly for both
3194 // the default voice channel and following ones.
3195 EXPECT_TRUE(channel_->AddRecvStream(sp));
3196 sp.ssrcs[0] += 1;
3197 EXPECT_TRUE(channel_->AddRecvStream(sp));
3198
Mirko Bonadeif859e552018-05-30 15:31:29 +02003199 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003200 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003201 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003202 << "SyncGroup should be set based on stream id";
3203 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003204 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003205 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003206}
3207
solenberg3a941542015-11-16 07:34:50 -08003208// TODO(solenberg): Remove, once recv streams are configured through Call.
3209// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003210TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003211 // Test that setting the header extensions results in the expected state
3212 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003213 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003214 ssrcs.push_back(223);
3215 ssrcs.push_back(224);
3216
solenbergff976312016-03-30 23:28:51 -07003217 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003218 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003219 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003220 EXPECT_TRUE(
3221 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 }
3223
Mirko Bonadeif859e552018-05-30 15:31:29 +02003224 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003225 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003226 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003227 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003228 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229 }
3230
3231 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003232 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003233 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003234 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003235 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003236 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003237 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003238 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003239 EXPECT_NE(nullptr, s);
3240 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003241 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3242 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003243 for (const auto& s_ext : s_exts) {
3244 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003245 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003246 }
3247 }
3248 }
3249 }
3250
3251 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003252 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003253 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003254 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003256 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003257 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258}
3259
3260TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3261 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003262 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003263 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003264 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003265 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3266 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003268 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269
solenbergff976312016-03-30 23:28:51 -07003270 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 cricket::WebRtcVoiceMediaChannel* media_channel =
3272 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003273 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003274 EXPECT_TRUE(media_channel->AddRecvStream(
3275 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3276
Mirko Bonadeif859e552018-05-30 15:31:29 +02003277 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003278 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003279 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003280 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003281 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003282 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003283 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003284 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003285}
Minyue2013aec2015-05-13 14:14:42 +02003286
solenberg0a617e22015-10-20 15:49:38 -07003287// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003288// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003289TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003290 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_TRUE(AddRecvStream(kSsrcY));
3292 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003293 EXPECT_TRUE(
3294 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003295 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3296 EXPECT_TRUE(AddRecvStream(kSsrcW));
3297 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003298}
3299
solenberg7602aab2016-11-14 11:30:07 -08003300TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3301 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003302 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003303 EXPECT_TRUE(
3304 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003305 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3306 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3307 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003308 EXPECT_TRUE(
3309 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003310 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3311 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003312}
stefan658910c2015-09-03 05:48:32 -07003313
deadbeef884f5852016-01-15 09:20:04 -08003314TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003315 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003316 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3317 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003318
3319 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003320 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3321 EXPECT_TRUE(AddRecvStream(kSsrcX));
3322 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003323
3324 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003325 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3326 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003327
3328 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003329 channel_->SetRawAudioSink(kSsrcX, nullptr);
3330 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003331}
3332
solenberg2100c0b2017-03-01 11:29:29 -08003333TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003334 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003335 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3336 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003337 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3338 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003339
3340 // Should be able to set a default sink even when no stream exists.
3341 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3342
solenberg2100c0b2017-03-01 11:29:29 -08003343 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3344 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003345 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003347
3348 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003349 channel_->SetRawAudioSink(kSsrc0, nullptr);
3350 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003351
3352 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003353 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3354 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003355
3356 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003357 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003358 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003359 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3360
3361 // Spawn another unsignaled stream - it should be assigned the default sink
3362 // and the previous unsignaled stream should lose it.
3363 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3364 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3365 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3366 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003367 if (kMaxUnsignaledRecvStreams > 1) {
3368 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3369 }
solenberg2100c0b2017-03-01 11:29:29 -08003370 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3371
3372 // Reset the default sink - the second unsignaled stream should lose it.
3373 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003374 if (kMaxUnsignaledRecvStreams > 1) {
3375 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3376 }
solenberg2100c0b2017-03-01 11:29:29 -08003377 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3378
3379 // Try setting the default sink while two streams exists.
3380 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003381 if (kMaxUnsignaledRecvStreams > 1) {
3382 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3383 }
solenberg2100c0b2017-03-01 11:29:29 -08003384 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3385
3386 // Try setting the sink for the first unsignaled stream using its known SSRC.
3387 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003388 if (kMaxUnsignaledRecvStreams > 1) {
3389 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3390 }
solenberg2100c0b2017-03-01 11:29:29 -08003391 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003392 if (kMaxUnsignaledRecvStreams > 1) {
3393 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3394 }
deadbeef884f5852016-01-15 09:20:04 -08003395}
3396
skvlad7a43d252016-03-22 15:32:27 -07003397// Test that, just like the video channel, the voice channel communicates the
3398// network state to the call.
3399TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003400 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003401
3402 EXPECT_EQ(webrtc::kNetworkUp,
3403 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3404 EXPECT_EQ(webrtc::kNetworkUp,
3405 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3406
3407 channel_->OnReadyToSend(false);
3408 EXPECT_EQ(webrtc::kNetworkDown,
3409 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3410 EXPECT_EQ(webrtc::kNetworkUp,
3411 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3412
3413 channel_->OnReadyToSend(true);
3414 EXPECT_EQ(webrtc::kNetworkUp,
3415 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3416 EXPECT_EQ(webrtc::kNetworkUp,
3417 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3418}
3419
aleloi18e0b672016-10-04 02:45:47 -07003420// Test that playout is still started after changing parameters
3421TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3422 SetupRecvStream();
3423 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003424 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003425
3426 // Changing RTP header extensions will recreate the AudioReceiveStream.
3427 cricket::AudioRecvParameters parameters;
3428 parameters.extensions.push_back(
3429 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3430 channel_->SetRecvParameters(parameters);
3431
solenberg2100c0b2017-03-01 11:29:29 -08003432 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003433}
3434
Zhi Huangfa266ef2017-12-13 10:27:46 -08003435// Tests when GetSources is called with non-existing ssrc, it will return an
3436// empty list of RtpSource without crashing.
3437TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3438 // Setup an recv stream with |kSsrcX|.
3439 SetupRecvStream();
3440 cricket::WebRtcVoiceMediaChannel* media_channel =
3441 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3442 // Call GetSources with |kSsrcY| which doesn't exist.
3443 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3444 EXPECT_EQ(0u, sources.size());
3445}
3446
stefan658910c2015-09-03 05:48:32 -07003447// Tests that the library initializes and shuts down properly.
3448TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003449 // If the VoiceEngine wants to gather available codecs early, that's fine but
3450 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003451 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3452 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003453 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003454 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003455 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003456 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003457 task_queue_factory.get(), &adm,
3458 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003459 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003460 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003461 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003462 webrtc::Call::Config call_config(&event_log);
3463 call_config.task_queue_factory = task_queue_factory.get();
3464 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003465 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3466 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3467 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003468 EXPECT_TRUE(channel != nullptr);
3469 delete channel;
solenbergff976312016-03-30 23:28:51 -07003470}
stefan658910c2015-09-03 05:48:32 -07003471
solenbergff976312016-03-30 23:28:51 -07003472// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003473TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003474 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3475 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003476 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003477 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003478 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003479 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003480 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003481 {
peaha9cc40b2017-06-29 08:32:09 -07003482 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003483 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003484 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003485 task_queue_factory.get(), &adm,
3486 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003487 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003488 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003489 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003490 webrtc::Call::Config call_config(&event_log);
3491 call_config.task_queue_factory = task_queue_factory.get();
3492 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003493 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3494 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3495 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003496 EXPECT_TRUE(channel != nullptr);
3497 delete channel;
3498 }
stefan658910c2015-09-03 05:48:32 -07003499}
3500
ossu20a4b3f2017-04-27 02:08:52 -07003501// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3502TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003503 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3504 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003505 // TODO(ossu): Why are the payload types of codecs with non-static payload
3506 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003507 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003508 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003509 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003510 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003511 task_queue_factory.get(), &adm,
3512 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003513 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003514 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003515 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003516 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003517 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003518 (clockrate == 0 || codec.clockrate == clockrate);
3519 };
3520 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003521 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003522 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003523 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003524 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003525 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003526 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003527 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003528 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003529 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003530 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003531 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003532 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3533 // Remove these checks once both send and receive side assigns payload
3534 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003535 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003536 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003537 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003538 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003539 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003540 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003541 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003542 EXPECT_EQ(111, codec.id);
3543 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3544 EXPECT_EQ("10", codec.params.find("minptime")->second);
3545 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3546 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003547 }
3548 }
stefan658910c2015-09-03 05:48:32 -07003549}
3550
3551// Tests that VoE supports at least 32 channels
3552TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003553 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3554 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003555 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003556 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003557 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003558 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003559 task_queue_factory.get(), &adm,
3560 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003561 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003562 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003563 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003564 webrtc::Call::Config call_config(&event_log);
3565 call_config.task_queue_factory = task_queue_factory.get();
3566 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
stefan658910c2015-09-03 05:48:32 -07003567
3568 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003569 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003570 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003571 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3572 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3573 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003574 if (!channel)
3575 break;
stefan658910c2015-09-03 05:48:32 -07003576 channels[num_channels++] = channel;
3577 }
3578
Mirko Bonadeif859e552018-05-30 15:31:29 +02003579 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003580 EXPECT_EQ(expected, num_channels);
3581
3582 while (num_channels > 0) {
3583 delete channels[--num_channels];
3584 }
stefan658910c2015-09-03 05:48:32 -07003585}
3586
3587// Test that we set our preferred codecs properly.
3588TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003589 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3590 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003591 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3592 // - Check that our builtin codecs are usable by Channel.
3593 // - The codecs provided by the engine is usable by Channel.
3594 // It does not check that the codecs in the RecvParameters are actually
3595 // what we sent in - though it's probably reasonable to expect so, if
3596 // SetRecvParameters returns true.
3597 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003598 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003599 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003600 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003601 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003602 task_queue_factory.get(), &adm,
3603 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003604 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003605 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003606 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003607 webrtc::Call::Config call_config(&event_log);
3608 call_config.task_queue_factory = task_queue_factory.get();
3609 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
nisse51542be2016-02-12 02:27:06 -08003610 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003611 cricket::AudioOptions(),
3612 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003613 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003614 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003615 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003616}
ossu9def8002017-02-09 05:14:32 -08003617
3618TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3619 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003620 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3621 {48000, 2, 16000, 10000, 20000}};
3622 spec1.info.allow_comfort_noise = false;
3623 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003624 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003625 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3626 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003627 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003628 specs.push_back(webrtc::AudioCodecSpec{
3629 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3630 {16000, 1, 13300}});
3631 specs.push_back(
3632 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3633 specs.push_back(
3634 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003635
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003636 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3637 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003638 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3639 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3640 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003641 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003642 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003643 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003644 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003645
peaha9cc40b2017-06-29 08:32:09 -07003646 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003647 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003648 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3649 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003650 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003651 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003652 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003653 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003654
3655 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3656 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003657 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3658 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3659 if (codecs.size() > index)
3660 return codecs[index];
3661 return missing_codec;
3662 };
ossu9def8002017-02-09 05:14:32 -08003663
3664 // Ensure the general codecs are generated first and in order.
3665 for (size_t i = 0; i != specs.size(); ++i) {
3666 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3667 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3668 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3669 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3670 }
3671
3672 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003673 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003674 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3675 for (size_t i = 0; i != codecs.size(); ++i) {
3676 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003677 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003678 codec.clockrate == format.clockrate_hz &&
3679 codec.channels == format.num_channels) {
3680 return rtc::checked_cast<int>(i);
3681 }
3682 }
3683 return -1;
3684 };
ossu9def8002017-02-09 05:14:32 -08003685
3686 // Ensure all supplementary codecs are generated last. Their internal ordering
3687 // is not important.
3688 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3689 const int num_specs = static_cast<int>(specs.size());
3690 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3691 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3692 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3693 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3694 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3695 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3696 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3697}