blob: 711cbbb8e615e4a621a459b8643ef0abfdefe990 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/webrtc_voice_engine.h"
12
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080015
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020016#include "absl/memory/memory.h"
Niels Möller2edab4c2018-10-22 09:48:08 +020017#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/audio_codecs/builtin_audio_decoder_factory.h"
19#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020020#include "api/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010022#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010023#include "api/task_queue/default_task_queue_factory.h"
Niels Möller65f17ca2019-09-12 13:59:36 +020024#include "api/transport/media/media_transport_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "call/call.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/fake_media_engine.h"
27#include "media/base/fake_network_interface.h"
28#include "media/base/fake_rtp.h"
29#include "media/base/media_constants.h"
30#include "media/engine/fake_webrtc_call.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/audio_device/include/mock_audio_device.h"
32#include "modules/audio_processing/include/mock_audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080034#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010035#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "test/field_trial.h"
37#include "test/gtest.h"
38#include "test/mock_audio_decoder_factory.h"
39#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
Elad Alon157540a2019-02-08 23:37:52 +010041using ::testing::_;
42using ::testing::ContainerEq;
43using ::testing::Contains;
44using ::testing::Field;
45using ::testing::Return;
46using ::testing::ReturnPointee;
47using ::testing::SaveArg;
48using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000049
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010051using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020052
solenberg418b7d32017-06-13 00:38:27 -070053constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070054
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
56const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070057const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
59const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070060const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
61const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020062const cricket::AudioCodec kTelephoneEventCodec1(106,
63 "telephone-event",
64 8000,
65 0,
66 1);
67const cricket::AudioCodec kTelephoneEventCodec2(107,
68 "telephone-event",
69 32000,
70 0,
71 1);
solenberg2779bab2016-11-17 04:45:19 -080072
solenberg2100c0b2017-03-01 11:29:29 -080073const uint32_t kSsrc0 = 0;
74const uint32_t kSsrc1 = 1;
75const uint32_t kSsrcX = 0x99;
76const uint32_t kSsrcY = 0x17;
77const uint32_t kSsrcZ = 0x42;
78const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020079const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080
solenberg971cab02016-06-14 10:02:41 -070081constexpr int kRtpHistoryMs = 5000;
82
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010083constexpr webrtc::AudioProcessing::Config::GainController1::Mode
84 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010085#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010086 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010087#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010088 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010089#endif
90
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;
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200569 stats.payload_bytes_sent = 345;
570 stats.header_and_padding_bytes_sent = 56;
solenberg85a04962015-10-27 03:35:21 -0700571 stats.packets_sent = 678;
572 stats.packets_lost = 9012;
573 stats.fraction_lost = 34.56f;
574 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100575 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700576 stats.jitter_ms = 12;
577 stats.rtt_ms = 345;
578 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100579 stats.apm_statistics.delay_median_ms = 234;
580 stats.apm_statistics.delay_standard_deviation_ms = 567;
581 stats.apm_statistics.echo_return_loss = 890;
582 stats.apm_statistics.echo_return_loss_enhancement = 1234;
583 stats.apm_statistics.residual_echo_likelihood = 0.432f;
584 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100585 stats.ana_statistics.bitrate_action_counter = 321;
586 stats.ana_statistics.channel_action_counter = 432;
587 stats.ana_statistics.dtx_action_counter = 543;
588 stats.ana_statistics.fec_action_counter = 654;
589 stats.ana_statistics.frame_length_increase_counter = 765;
590 stats.ana_statistics.frame_length_decrease_counter = 876;
591 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700592 stats.typing_noise_detected = true;
593 return stats;
594 }
595 void SetAudioSendStreamStats() {
596 for (auto* s : call_.GetAudioSendStreams()) {
597 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200598 }
solenberg85a04962015-10-27 03:35:21 -0700599 }
solenberg566ef242015-11-06 15:34:49 -0800600 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
601 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700602 const auto stats = GetAudioSendStreamStats();
603 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200604 EXPECT_EQ(info.payload_bytes_sent, stats.payload_bytes_sent);
605 EXPECT_EQ(info.header_and_padding_bytes_sent,
606 stats.header_and_padding_bytes_sent);
solenberg85a04962015-10-27 03:35:21 -0700607 EXPECT_EQ(info.packets_sent, stats.packets_sent);
608 EXPECT_EQ(info.packets_lost, stats.packets_lost);
609 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
610 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800611 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700612 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
613 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
614 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100615 EXPECT_EQ(info.apm_statistics.delay_median_ms,
616 stats.apm_statistics.delay_median_ms);
617 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
618 stats.apm_statistics.delay_standard_deviation_ms);
619 EXPECT_EQ(info.apm_statistics.echo_return_loss,
620 stats.apm_statistics.echo_return_loss);
621 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
622 stats.apm_statistics.echo_return_loss_enhancement);
623 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
624 stats.apm_statistics.residual_echo_likelihood);
625 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
626 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700627 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
628 stats.ana_statistics.bitrate_action_counter);
629 EXPECT_EQ(info.ana_statistics.channel_action_counter,
630 stats.ana_statistics.channel_action_counter);
631 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
632 stats.ana_statistics.dtx_action_counter);
633 EXPECT_EQ(info.ana_statistics.fec_action_counter,
634 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700635 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
636 stats.ana_statistics.frame_length_increase_counter);
637 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
638 stats.ana_statistics.frame_length_decrease_counter);
639 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
640 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800641 EXPECT_EQ(info.typing_noise_detected,
642 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700643 }
644
645 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
646 webrtc::AudioReceiveStream::Stats stats;
647 stats.remote_ssrc = 123;
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200648 stats.payload_bytes_rcvd = 456;
649 stats.header_and_padding_bytes_rcvd = 67;
solenberg85a04962015-10-27 03:35:21 -0700650 stats.packets_rcvd = 768;
651 stats.packets_lost = 101;
solenberg85a04962015-10-27 03:35:21 -0700652 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100653 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700654 stats.jitter_ms = 901;
655 stats.jitter_buffer_ms = 234;
656 stats.jitter_buffer_preferred_ms = 567;
657 stats.delay_estimate_ms = 890;
658 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700659 stats.total_samples_received = 5678901;
660 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200661 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200662 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100663 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700664 stats.expand_rate = 5.67f;
665 stats.speech_expand_rate = 8.90f;
666 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200667 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700668 stats.accelerate_rate = 4.56f;
669 stats.preemptive_expand_rate = 7.89f;
670 stats.decoding_calls_to_silence_generator = 12;
671 stats.decoding_calls_to_neteq = 345;
672 stats.decoding_normal = 67890;
673 stats.decoding_plc = 1234;
Alex Narest5b5d97c2019-08-07 18:15:08 +0200674 stats.decoding_codec_plc = 1236;
solenberg85a04962015-10-27 03:35:21 -0700675 stats.decoding_cng = 5678;
676 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700677 stats.decoding_muted_output = 3456;
678 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200679 return stats;
680 }
681 void SetAudioReceiveStreamStats() {
682 for (auto* s : call_.GetAudioReceiveStreams()) {
683 s->SetStats(GetAudioReceiveStreamStats());
684 }
685 }
686 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700687 const auto stats = GetAudioReceiveStreamStats();
688 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200689 EXPECT_EQ(info.payload_bytes_rcvd, stats.payload_bytes_rcvd);
690 EXPECT_EQ(info.header_and_padding_bytes_rcvd,
691 stats.header_and_padding_bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
693 stats.packets_rcvd);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
695 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700696 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800697 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
699 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
700 stats.jitter_buffer_ms);
701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700702 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200703 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
704 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700705 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700706 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
707 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200708 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200709 EXPECT_EQ(info.jitter_buffer_delay_seconds,
710 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100711 EXPECT_EQ(info.jitter_buffer_emitted_count,
712 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700713 EXPECT_EQ(info.expand_rate, stats.expand_rate);
714 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
715 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200716 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700717 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
718 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200719 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700720 stats.decoding_calls_to_silence_generator);
721 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
722 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
723 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
Alex Narest5b5d97c2019-08-07 18:15:08 +0200724 EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
solenberg85a04962015-10-27 03:35:21 -0700725 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
726 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700727 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700728 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200729 }
hbos1acfbd22016-11-17 23:43:29 -0800730 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
731 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
732 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
733 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
734 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
735 codec.ToCodecParameters());
736 }
737 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
738 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
739 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
740 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
741 codec.ToCodecParameters());
742 }
743 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200744
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100745 void VerifyGainControlEnabledCorrectly() {
746 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
747 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
748 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
749 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
750 }
751
752 void VerifyGainControlDefaultSettings() {
753 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
754 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
755 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
756 }
757
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200758 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100759 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200760 }
761
peah8271d042016-11-22 07:24:52 -0800762 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100763 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800764 }
765
Sam Zackrissonba502232019-01-04 10:36:48 +0100766 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100767 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100768 }
769
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100771 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700772 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700773 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800774 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200775 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700776 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700777 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200778 cricket::AudioSendParameters send_parameters_;
779 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800780 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700781 webrtc::AudioProcessing::Config apm_config_;
782
stefanba4c0e42016-02-04 04:12:24 -0800783 private:
784 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785};
786
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100788TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
solenberg31fec402016-05-06 02:13:12 -0700792// Test that we can add a send stream and that it has the correct defaults.
793TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
794 EXPECT_TRUE(SetupChannel());
795 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800796 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
797 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
798 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700799 EXPECT_EQ("", config.rtp.c_name);
800 EXPECT_EQ(0u, config.rtp.extensions.size());
801 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
802 config.send_transport);
803}
804
805// Test that we can add a receive stream and that it has the correct defaults.
806TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
807 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800808 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700809 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800810 GetRecvStreamConfig(kSsrcX);
811 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700812 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
813 EXPECT_FALSE(config.rtp.transport_cc);
814 EXPECT_EQ(0u, config.rtp.extensions.size());
815 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
816 config.rtcp_send_transport);
817 EXPECT_EQ("", config.sync_group);
818}
819
stefanba4c0e42016-02-04 04:12:24 -0800820TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700821 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800822 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100823 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800824 if (codec.name == "opus") {
825 EXPECT_TRUE(HasTransportCc(codec));
826 opus_found = true;
827 }
828 }
829 EXPECT_TRUE(opus_found);
830}
831
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832// Test that we set our inbound codecs properly, including changing PT.
833TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700834 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200835 cricket::AudioRecvParameters parameters;
836 parameters.codecs.push_back(kIsacCodec);
837 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800838 parameters.codecs.push_back(kTelephoneEventCodec1);
839 parameters.codecs.push_back(kTelephoneEventCodec2);
840 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 parameters.codecs[2].id = 126;
842 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800843 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700844 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
845 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
846 {{0, {"PCMU", 8000, 1}},
847 {106, {"ISAC", 16000, 1}},
848 {126, {"telephone-event", 8000, 1}},
849 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850}
851
852// Test that we fail to set an unknown inbound codec.
853TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700854 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 cricket::AudioRecvParameters parameters;
856 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700857 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859}
860
861// Test that we fail if we have duplicate types in the inbound list.
862TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700863 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 cricket::AudioRecvParameters parameters;
865 parameters.codecs.push_back(kIsacCodec);
866 parameters.codecs.push_back(kCn16000Codec);
867 parameters.codecs[1].id = kIsacCodec.id;
868 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869}
870
871// Test that we can decode OPUS without stereo parameters.
872TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700873 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200874 cricket::AudioRecvParameters parameters;
875 parameters.codecs.push_back(kIsacCodec);
876 parameters.codecs.push_back(kPcmuCodec);
877 parameters.codecs.push_back(kOpusCodec);
878 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800879 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700880 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
881 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
882 {{0, {"PCMU", 8000, 1}},
883 {103, {"ISAC", 16000, 1}},
884 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885}
886
887// Test that we can decode OPUS with stereo = 0.
888TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700889 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200890 cricket::AudioRecvParameters parameters;
891 parameters.codecs.push_back(kIsacCodec);
892 parameters.codecs.push_back(kPcmuCodec);
893 parameters.codecs.push_back(kOpusCodec);
894 parameters.codecs[2].params["stereo"] = "0";
895 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800896 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700897 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
898 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
899 {{0, {"PCMU", 8000, 1}},
900 {103, {"ISAC", 16000, 1}},
901 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902}
903
904// Test that we can decode OPUS with stereo = 1.
905TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700906 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 cricket::AudioRecvParameters parameters;
908 parameters.codecs.push_back(kIsacCodec);
909 parameters.codecs.push_back(kPcmuCodec);
910 parameters.codecs.push_back(kOpusCodec);
911 parameters.codecs[2].params["stereo"] = "1";
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800913 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700914 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
915 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
916 {{0, {"PCMU", 8000, 1}},
917 {103, {"ISAC", 16000, 1}},
918 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919}
920
921// Test that changes to recv codecs are applied to all streams.
922TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700923 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 cricket::AudioRecvParameters parameters;
925 parameters.codecs.push_back(kIsacCodec);
926 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800927 parameters.codecs.push_back(kTelephoneEventCodec1);
928 parameters.codecs.push_back(kTelephoneEventCodec2);
929 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200930 parameters.codecs[2].id = 126;
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700932 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
933 EXPECT_TRUE(AddRecvStream(ssrc));
934 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
935 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
936 {{0, {"PCMU", 8000, 1}},
937 {106, {"ISAC", 16000, 1}},
938 {126, {"telephone-event", 8000, 1}},
939 {107, {"telephone-event", 32000, 1}}})));
940 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941}
942
943TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700944 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 cricket::AudioRecvParameters parameters;
946 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800947 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200948 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
solenberg2100c0b2017-03-01 11:29:29 -0800950 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200951 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800952 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953}
954
955// Test that we can apply the same set of codecs again while playing.
956TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700957 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200958 cricket::AudioRecvParameters parameters;
959 parameters.codecs.push_back(kIsacCodec);
960 parameters.codecs.push_back(kCn16000Codec);
961 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700962 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200963 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
deadbeefcb383672017-04-26 16:28:42 -0700965 // Remapping a payload type to a different codec should fail.
966 parameters.codecs[0] = kOpusCodec;
967 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200968 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800969 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970}
971
972// Test that we can add a codec while playing.
973TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700974 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 cricket::AudioRecvParameters parameters;
976 parameters.codecs.push_back(kIsacCodec);
977 parameters.codecs.push_back(kCn16000Codec);
978 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700979 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200981 parameters.codecs.push_back(kOpusCodec);
982 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800983 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984}
985
deadbeefcb383672017-04-26 16:28:42 -0700986// Test that we accept adding the same codec with a different payload type.
987// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
988TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
989 EXPECT_TRUE(SetupRecvStream());
990 cricket::AudioRecvParameters parameters;
991 parameters.codecs.push_back(kIsacCodec);
992 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
993
994 ++parameters.codecs[0].id;
995 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
996}
997
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700999 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001001 // Test that when autobw is enabled, bitrate is kept as the default
1002 // value. autobw is enabled for the following tests because the target
1003 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
1008 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001009 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010
ossu20a4b3f2017-04-27 02:08:52 -07001011 // opus, default bitrate == 32000 in mono.
1012 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013}
1014
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001015TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001016 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001019 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1020 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001021 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001024 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1025 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1026 // Rates above the max (510000) should be capped.
1027 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028}
1029
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001030TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001031 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001032
1033 // Test that we can only set a maximum bitrate for a fixed-rate codec
1034 // if it's bigger than the fixed rate.
1035
1036 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001037 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1041 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1042 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1043 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001044}
1045
1046TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001047 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001048 const int kDesiredBitrate = 128000;
1049 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001050 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001051 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001052 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001053
Yves Gerey665174f2018-06-19 15:03:05 +02001054 EXPECT_TRUE(
1055 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001056
solenberg2100c0b2017-03-01 11:29:29 -08001057 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001058}
1059
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001060// Test that bitrate cannot be set for CBR codecs.
1061// Bitrate is ignored if it is higher than the fixed bitrate.
1062// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001063TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001064 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065
1066 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001067 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001068 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001069
1070 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001071 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001072 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001073
1074 send_parameters_.max_bandwidth_bps = 128;
1075 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001076 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001077}
1078
skvlade0d46372016-04-07 22:59:22 -07001079// Test that the per-stream bitrate limit and the global
1080// bitrate limit both apply.
1081TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1082 EXPECT_TRUE(SetupSendStream());
1083
ossu20a4b3f2017-04-27 02:08:52 -07001084 // opus, default bitrate == 32000.
1085 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001086 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1087 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1088 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1089
1090 // CBR codecs allow both maximums to exceed the bitrate.
1091 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1093 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1094 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1095
1096 // CBR codecs don't allow per stream maximums to be too low.
1097 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1098 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1099}
1100
1101// Test that an attempt to set RtpParameters for a stream that does not exist
1102// fails.
1103TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1104 EXPECT_TRUE(SetupChannel());
1105 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001106 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001107 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001108
1109 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001110 EXPECT_FALSE(
1111 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001112}
1113
1114TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001115 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001116 // This test verifies that setting RtpParameters succeeds only if
1117 // the structure contains exactly one encoding.
1118 // TODO(skvlad): Update this test when we start supporting setting parameters
1119 // for each encoding individually.
1120
1121 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001122 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001123 // Two or more encodings should result in failure.
1124 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001125 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001126 // Zero encodings should also fail.
1127 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001128 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001129}
1130
1131// Changing the SSRC through RtpParameters is not allowed.
1132TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1133 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001134 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001135 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001136 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001137}
1138
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001141TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1142 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001143 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001144 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001145 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001146 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001147 ASSERT_EQ(1u, parameters.encodings.size());
1148 ASSERT_TRUE(parameters.encodings[0].active);
1149 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001150 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001151 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001152
1153 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001154 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001155 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001156 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001157 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001158 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001159}
1160
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001161// Test that SetRtpSendParameters configures the correct encoding channel for
1162// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001163TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1164 SetupForMultiSendStream();
1165 // Create send streams.
1166 for (uint32_t ssrc : kSsrcs4) {
1167 EXPECT_TRUE(
1168 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1169 }
1170 // Configure one stream to be limited by the stream config, another to be
1171 // limited by the global max, and the third one with no per-stream limit
1172 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001173 SetGlobalMaxBitrate(kOpusCodec, 32000);
1174 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1175 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001176 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1177
ossu20a4b3f2017-04-27 02:08:52 -07001178 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1179 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1180 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001181
1182 // Remove the global cap; the streams should switch to their respective
1183 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001184 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001185 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1186 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1187 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001188}
1189
Tim Haloun648d28a2018-10-18 16:52:22 -07001190// RTCRtpEncodingParameters.network_priority must be one of a few values
1191// derived from the default priority, corresponding to very-low, low, medium,
1192// or high.
1193TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1194 EXPECT_TRUE(SetupSendStream());
1195 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1196 EXPECT_EQ(1UL, parameters.encodings.size());
1197 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1198 parameters.encodings[0].network_priority);
1199
1200 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1201 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1202 for (auto it : good_values) {
1203 parameters.encodings[0].network_priority = it;
1204 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1205 }
1206 for (auto it : bad_values) {
1207 parameters.encodings[0].network_priority = it;
1208 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1209 }
1210}
1211
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001212// Test that GetRtpSendParameters returns the currently configured codecs.
1213TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001214 EXPECT_TRUE(SetupSendStream());
1215 cricket::AudioSendParameters parameters;
1216 parameters.codecs.push_back(kIsacCodec);
1217 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001218 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001219
solenberg2100c0b2017-03-01 11:29:29 -08001220 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001222 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1223 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001224}
1225
Florent Castellidacec712018-05-24 16:24:21 +02001226// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1227TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1228 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1229 params.cname = "rtcpcname";
1230 EXPECT_TRUE(SetupSendStream(params));
1231
1232 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1233 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1234}
1235
Florent Castelliabe301f2018-06-12 18:33:49 +02001236TEST_F(WebRtcVoiceEngineTestFake,
1237 DetectRtpSendParameterHeaderExtensionsChange) {
1238 EXPECT_TRUE(SetupSendStream());
1239
1240 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1241 rtp_parameters.header_extensions.emplace_back();
1242
1243 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1244
1245 webrtc::RTCError result =
1246 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1247 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1248}
1249
deadbeefcb443432016-12-12 11:12:36 -08001250// Test that GetRtpSendParameters returns an SSRC.
1251TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1252 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001253 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001254 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001255 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001256}
1257
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001258// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001259TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001260 EXPECT_TRUE(SetupSendStream());
1261 cricket::AudioSendParameters parameters;
1262 parameters.codecs.push_back(kIsacCodec);
1263 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001264 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001265
solenberg2100c0b2017-03-01 11:29:29 -08001266 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001267
1268 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001269 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001270
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001271 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001272 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1273 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001274}
1275
minyuececec102017-03-27 13:04:25 -07001276// Test that max_bitrate_bps in send stream config gets updated correctly when
1277// SetRtpSendParameters is called.
1278TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1279 webrtc::test::ScopedFieldTrials override_field_trials(
1280 "WebRTC-Audio-SendSideBwe/Enabled/");
1281 EXPECT_TRUE(SetupSendStream());
1282 cricket::AudioSendParameters send_parameters;
1283 send_parameters.codecs.push_back(kOpusCodec);
1284 SetSendParameters(send_parameters);
1285
1286 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1287 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1288 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1289
1290 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001291 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001292 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001293
1294 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1295 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1296}
1297
Seth Hampson24722b32017-12-22 09:36:42 -08001298// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1299// a value <= 0, setting the parameters returns false.
1300TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1301 EXPECT_TRUE(SetupSendStream());
1302 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1303 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1304 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1305 rtp_parameters.encodings[0].bitrate_priority);
1306
1307 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001308 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001309 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001310 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001311}
1312
1313// Test that the bitrate_priority in the send stream config gets updated when
1314// SetRtpSendParameters is set for the VoiceMediaChannel.
1315TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1316 EXPECT_TRUE(SetupSendStream());
1317 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1318
1319 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1320 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1321 rtp_parameters.encodings[0].bitrate_priority);
1322 double new_bitrate_priority = 2.0;
1323 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001324 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001325
1326 // The priority should get set for both the audio channel's rtp parameters
1327 // and the audio send stream's audio config.
1328 EXPECT_EQ(
1329 new_bitrate_priority,
1330 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1331 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1332}
1333
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001334// Test that GetRtpReceiveParameters returns the currently configured codecs.
1335TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1336 EXPECT_TRUE(SetupRecvStream());
1337 cricket::AudioRecvParameters parameters;
1338 parameters.codecs.push_back(kIsacCodec);
1339 parameters.codecs.push_back(kPcmuCodec);
1340 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1341
1342 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001343 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001344 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1345 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1346 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1347}
1348
deadbeefcb443432016-12-12 11:12:36 -08001349// Test that GetRtpReceiveParameters returns an SSRC.
1350TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1351 EXPECT_TRUE(SetupRecvStream());
1352 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001353 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001354 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001355 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001356}
1357
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001358// Test that if we set/get parameters multiple times, we get the same results.
1359TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1360 EXPECT_TRUE(SetupRecvStream());
1361 cricket::AudioRecvParameters parameters;
1362 parameters.codecs.push_back(kIsacCodec);
1363 parameters.codecs.push_back(kPcmuCodec);
1364 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1365
1366 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001367 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001368
1369 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001370 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001371
1372 // ... And this shouldn't change the params returned by
1373 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001374 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1375 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001376}
1377
deadbeef3bc15102017-04-20 19:25:07 -07001378// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1379// aren't signaled. It should return an empty "RtpEncodingParameters" when
1380// configured to receive an unsignaled stream and no packets have been received
1381// yet, and start returning the SSRC once a packet has been received.
1382TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1383 ASSERT_TRUE(SetupChannel());
1384 // Call necessary methods to configure receiving a default stream as
1385 // soon as it arrives.
1386 cricket::AudioRecvParameters parameters;
1387 parameters.codecs.push_back(kIsacCodec);
1388 parameters.codecs.push_back(kPcmuCodec);
1389 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1390
1391 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1392 // stream. Should return nothing.
1393 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1394
1395 // Set a sink for an unsignaled stream.
1396 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1397 // Value of "0" means "unsignaled stream".
1398 channel_->SetRawAudioSink(0, std::move(fake_sink));
1399
1400 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1401 // in this method means "unsignaled stream".
1402 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1403 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1404 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1405
1406 // Receive PCMU packet (SSRC=1).
1407 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1408
1409 // The |ssrc| member should still be unset.
1410 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1411 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1412 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1413}
1414
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415// Test that we apply codecs properly.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kIsacCodec);
1420 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001421 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001422 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001423 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001424 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001425 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1426 EXPECT_EQ(96, send_codec_spec.payload_type);
1427 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1428 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1429 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001430 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001431 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001432}
1433
ossu20a4b3f2017-04-27 02:08:52 -07001434// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1435// AudioSendStream.
1436TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001437 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 cricket::AudioSendParameters parameters;
1439 parameters.codecs.push_back(kIsacCodec);
1440 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001441 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 parameters.codecs[0].id = 96;
1443 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001444 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001445 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001446 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001447 // Calling SetSendCodec again with same codec which is already set.
1448 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001449 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001450 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001451}
1452
ossu20a4b3f2017-04-27 02:08:52 -07001453// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1454// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001455
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001456// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001458 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 cricket::AudioSendParameters parameters;
1460 parameters.codecs.push_back(kOpusCodec);
1461 parameters.codecs[0].bitrate = 0;
1462 parameters.codecs[0].clockrate = 50000;
1463 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464}
1465
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001466// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001468 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001469 cricket::AudioSendParameters parameters;
1470 parameters.codecs.push_back(kOpusCodec);
1471 parameters.codecs[0].bitrate = 0;
1472 parameters.codecs[0].channels = 0;
1473 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474}
1475
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001476// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001478 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 cricket::AudioSendParameters parameters;
1480 parameters.codecs.push_back(kOpusCodec);
1481 parameters.codecs[0].bitrate = 0;
1482 parameters.codecs[0].channels = 0;
1483 parameters.codecs[0].params["stereo"] = "1";
1484 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485}
1486
1487// Test that if channel is 1 for opus and there's no stereo, we fail.
1488TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001489 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001490 cricket::AudioSendParameters parameters;
1491 parameters.codecs.push_back(kOpusCodec);
1492 parameters.codecs[0].bitrate = 0;
1493 parameters.codecs[0].channels = 1;
1494 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495}
1496
1497// Test that if channel is 1 for opus and stereo=0, we fail.
1498TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001499 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001500 cricket::AudioSendParameters parameters;
1501 parameters.codecs.push_back(kOpusCodec);
1502 parameters.codecs[0].bitrate = 0;
1503 parameters.codecs[0].channels = 1;
1504 parameters.codecs[0].params["stereo"] = "0";
1505 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001506}
1507
1508// Test that if channel is 1 for opus and stereo=1, we fail.
1509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 cricket::AudioSendParameters parameters;
1512 parameters.codecs.push_back(kOpusCodec);
1513 parameters.codecs[0].bitrate = 0;
1514 parameters.codecs[0].channels = 1;
1515 parameters.codecs[0].params["stereo"] = "1";
1516 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517}
1518
ossu20a4b3f2017-04-27 02:08:52 -07001519// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001520TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001521 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 cricket::AudioSendParameters parameters;
1523 parameters.codecs.push_back(kOpusCodec);
1524 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001526 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
ossu20a4b3f2017-04-27 02:08:52 -07001529// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 cricket::AudioSendParameters parameters;
1533 parameters.codecs.push_back(kOpusCodec);
1534 parameters.codecs[0].bitrate = 0;
1535 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001536 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001537 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538}
1539
ossu20a4b3f2017-04-27 02:08:52 -07001540// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001541TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001542 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001543 cricket::AudioSendParameters parameters;
1544 parameters.codecs.push_back(kOpusCodec);
1545 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001546 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001547 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001548 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001549 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001550
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001553 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001554}
1555
ossu20a4b3f2017-04-27 02:08:52 -07001556// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001557TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001558 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001559 cricket::AudioSendParameters parameters;
1560 parameters.codecs.push_back(kOpusCodec);
1561 parameters.codecs[0].bitrate = 0;
1562 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001564 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565}
1566
ossu20a4b3f2017-04-27 02:08:52 -07001567// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001568TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001569 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001570 cricket::AudioSendParameters parameters;
1571 parameters.codecs.push_back(kOpusCodec);
1572 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001573 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001574 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001575 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001576 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001577
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001578 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001579 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001580 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001581}
1582
ossu20a4b3f2017-04-27 02:08:52 -07001583// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001584TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001585 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001586 cricket::AudioSendParameters parameters;
1587 parameters.codecs.push_back(kOpusCodec);
1588 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001590 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1591 EXPECT_EQ(111, spec.payload_type);
1592 EXPECT_EQ(96000, spec.target_bitrate_bps);
1593 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001594 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001595 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596}
1597
ossu20a4b3f2017-04-27 02:08:52 -07001598// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001600 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001601 cricket::AudioSendParameters parameters;
1602 parameters.codecs.push_back(kOpusCodec);
1603 parameters.codecs[0].bitrate = 30000;
1604 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001606 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607}
1608
ossu20a4b3f2017-04-27 02:08:52 -07001609// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001611 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001612 cricket::AudioSendParameters parameters;
1613 parameters.codecs.push_back(kOpusCodec);
1614 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001616 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617}
1618
ossu20a4b3f2017-04-27 02:08:52 -07001619// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001620TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001621 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001622 cricket::AudioSendParameters parameters;
1623 parameters.codecs.push_back(kOpusCodec);
1624 parameters.codecs[0].bitrate = 30000;
1625 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001627 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001628}
1629
stefan13f1a0a2016-11-30 07:22:58 -08001630TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1631 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1632 200000);
1633}
1634
1635TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1636 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1637}
1638
1639TEST_F(WebRtcVoiceEngineTestFake,
1640 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1641 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1642}
1643
1644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1645 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1646}
1647
Yves Gerey665174f2018-06-19 15:03:05 +02001648TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001649 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1650 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001651 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001652 // Setting max bitrate should keep previous min bitrate
1653 // Setting max bitrate should not reset start bitrate.
1654 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1655 SetSdpBitrateParameters(
1656 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1657 Field(&BitrateConstraints::start_bitrate_bps, -1),
1658 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001659 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001660}
1661
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001662// Test that we can enable NACK with opus as callee.
1663TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001664 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001665 cricket::AudioSendParameters parameters;
1666 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001667 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1668 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001669 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001670 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001671 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001672 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001673
Yves Gerey665174f2018-06-19 15:03:05 +02001674 EXPECT_TRUE(
1675 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001676}
1677
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678// Test that we can enable NACK on receive streams.
1679TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001680 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001681 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001682 cricket::AudioSendParameters parameters;
1683 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001684 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1685 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001686 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689}
1690
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001691// Test that we can disable NACK on receive streams.
1692TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001693 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 cricket::AudioSendParameters parameters;
1696 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001697 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1698 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001699 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001700 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 parameters.codecs.clear();
1703 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001704 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001705 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001706}
1707
1708// Test that NACK is enabled on a new receive stream.
1709TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 cricket::AudioSendParameters parameters;
1712 parameters.codecs.push_back(kIsacCodec);
1713 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001714 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1715 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717
solenberg2100c0b2017-03-01 11:29:29 -08001718 EXPECT_TRUE(AddRecvStream(kSsrcY));
1719 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1720 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1721 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001722}
1723
stefanba4c0e42016-02-04 04:12:24 -08001724TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001725 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001726 cricket::AudioSendParameters send_parameters;
1727 send_parameters.codecs.push_back(kOpusCodec);
1728 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001730
1731 cricket::AudioRecvParameters recv_parameters;
1732 recv_parameters.codecs.push_back(kIsacCodec);
1733 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001734 EXPECT_TRUE(AddRecvStream(kSsrcX));
1735 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001736 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001737 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001738
ossudedfd282016-06-14 07:12:39 -07001739 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001740 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001741 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001742 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001743 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001744}
1745
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001746// Test that we can switch back and forth between Opus and ISAC with CN.
1747TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001748 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001749
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001750 cricket::AudioSendParameters opus_parameters;
1751 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001752 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001753 {
ossu20a4b3f2017-04-27 02:08:52 -07001754 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1755 EXPECT_EQ(111, spec.payload_type);
1756 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001757 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 cricket::AudioSendParameters isac_parameters;
1760 isac_parameters.codecs.push_back(kIsacCodec);
1761 isac_parameters.codecs.push_back(kCn16000Codec);
1762 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001763 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001764 {
ossu20a4b3f2017-04-27 02:08:52 -07001765 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1766 EXPECT_EQ(103, spec.payload_type);
1767 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001768 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001769
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001771 {
ossu20a4b3f2017-04-27 02:08:52 -07001772 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1773 EXPECT_EQ(111, spec.payload_type);
1774 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001775 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776}
1777
1778// Test that we handle various ways of specifying bitrate.
1779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001780 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001781 cricket::AudioSendParameters parameters;
1782 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001783 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001784 {
ossu20a4b3f2017-04-27 02:08:52 -07001785 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1786 EXPECT_EQ(103, spec.payload_type);
1787 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1788 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001789 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001790
Yves Gerey665174f2018-06-19 15:03:05 +02001791 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001792 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001793 {
ossu20a4b3f2017-04-27 02:08:52 -07001794 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1795 EXPECT_EQ(103, spec.payload_type);
1796 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1797 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001798 }
Yves Gerey665174f2018-06-19 15:03:05 +02001799 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001800 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001801 {
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_EQ(103, spec.payload_type);
1804 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1805 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001806 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807
Yves Gerey665174f2018-06-19 15:03:05 +02001808 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001809 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001810 {
ossu20a4b3f2017-04-27 02:08:52 -07001811 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1812 EXPECT_EQ(0, spec.payload_type);
1813 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1814 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001815 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816
Yves Gerey665174f2018-06-19 15:03:05 +02001817 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001818 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001819 {
ossu20a4b3f2017-04-27 02:08:52 -07001820 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1821 EXPECT_EQ(0, spec.payload_type);
1822 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1823 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001824 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001827 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001829 {
ossu20a4b3f2017-04-27 02:08:52 -07001830 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1831 EXPECT_EQ(111, spec.payload_type);
1832 EXPECT_STREQ("opus", spec.format.name.c_str());
1833 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001834 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835}
1836
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001837// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 cricket::AudioSendParameters parameters;
1841 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001842}
1843
1844// Test that we can set send codecs even with telephone-event codec as the first
1845// one on the list.
1846TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001847 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001849 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001850 parameters.codecs.push_back(kIsacCodec);
1851 parameters.codecs.push_back(kPcmuCodec);
1852 parameters.codecs[0].id = 98; // DTMF
1853 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001854 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001855 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1856 EXPECT_EQ(96, spec.payload_type);
1857 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001858 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001859 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001860}
1861
Harald Alvestranda1f66612018-02-21 11:24:23 +01001862// Test that CanInsertDtmf() is governed by the send flag
1863TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1864 EXPECT_TRUE(SetupSendStream());
1865 cricket::AudioSendParameters parameters;
1866 parameters.codecs.push_back(kTelephoneEventCodec1);
1867 parameters.codecs.push_back(kPcmuCodec);
1868 parameters.codecs[0].id = 98; // DTMF
1869 parameters.codecs[1].id = 96;
1870 SetSendParameters(parameters);
1871 EXPECT_FALSE(channel_->CanInsertDtmf());
1872 SetSend(true);
1873 EXPECT_TRUE(channel_->CanInsertDtmf());
1874 SetSend(false);
1875 EXPECT_FALSE(channel_->CanInsertDtmf());
1876}
1877
solenberg31642aa2016-03-14 08:00:37 -07001878// Test that payload type range is limited for telephone-event codec.
1879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001881 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001882 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001883 parameters.codecs.push_back(kIsacCodec);
1884 parameters.codecs[0].id = 0; // DTMF
1885 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001886 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001887 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001888 EXPECT_TRUE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = 128; // DTMF
1890 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1891 EXPECT_FALSE(channel_->CanInsertDtmf());
1892 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001894 EXPECT_TRUE(channel_->CanInsertDtmf());
1895 parameters.codecs[0].id = -1; // DTMF
1896 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1897 EXPECT_FALSE(channel_->CanInsertDtmf());
1898}
1899
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001900// Test that we can set send codecs even with CN codec as the first
1901// one on the list.
1902TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001903 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001904 cricket::AudioSendParameters parameters;
1905 parameters.codecs.push_back(kCn16000Codec);
1906 parameters.codecs.push_back(kIsacCodec);
1907 parameters.codecs.push_back(kPcmuCodec);
1908 parameters.codecs[0].id = 98; // wideband CN
1909 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001910 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001911 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1912 EXPECT_EQ(96, send_codec_spec.payload_type);
1913 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001914 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001915}
1916
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001917// Test that we set VAD and DTMF types correctly as caller.
1918TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001919 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001920 cricket::AudioSendParameters parameters;
1921 parameters.codecs.push_back(kIsacCodec);
1922 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001923 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 parameters.codecs.push_back(kCn16000Codec);
1925 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001926 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001927 parameters.codecs[0].id = 96;
1928 parameters.codecs[2].id = 97; // wideband CN
1929 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001930 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001931 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1932 EXPECT_EQ(96, send_codec_spec.payload_type);
1933 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001934 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001935 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001936 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001937 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001938}
1939
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001940// Test that we set VAD and DTMF types correctly as callee.
1941TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001942 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001943 cricket::AudioSendParameters parameters;
1944 parameters.codecs.push_back(kIsacCodec);
1945 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001946 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001947 parameters.codecs.push_back(kCn16000Codec);
1948 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001949 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 parameters.codecs[0].id = 96;
1951 parameters.codecs[2].id = 97; // wideband CN
1952 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001953 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001954 EXPECT_TRUE(
1955 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001956
ossu20a4b3f2017-04-27 02:08:52 -07001957 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1958 EXPECT_EQ(96, send_codec_spec.payload_type);
1959 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001960 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001961 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001962 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001963 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001964}
1965
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966// Test that we only apply VAD if we have a CN codec that matches the
1967// send codec clockrate.
1968TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001969 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001971 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 parameters.codecs.push_back(kIsacCodec);
1973 parameters.codecs.push_back(kCn16000Codec);
1974 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001975 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001976 {
ossu20a4b3f2017-04-27 02:08:52 -07001977 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1978 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001979 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001980 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001981 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001982 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001983 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001985 {
ossu20a4b3f2017-04-27 02:08:52 -07001986 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1987 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001988 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001989 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001990 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001991 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001993 {
ossu20a4b3f2017-04-27 02:08:52 -07001994 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1995 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001996 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001997 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001998 }
Brave Yao5225dd82015-03-26 07:39:19 +08001999 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002000 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002001 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002002 {
ossu20a4b3f2017-04-27 02:08:52 -07002003 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2004 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002005 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002006 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002007}
2008
2009// Test that we perform case-insensitive matching of codec names.
2010TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002011 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 cricket::AudioSendParameters parameters;
2013 parameters.codecs.push_back(kIsacCodec);
2014 parameters.codecs.push_back(kPcmuCodec);
2015 parameters.codecs.push_back(kCn16000Codec);
2016 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002017 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002018 parameters.codecs[0].name = "iSaC";
2019 parameters.codecs[0].id = 96;
2020 parameters.codecs[2].id = 97; // wideband CN
2021 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002022 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002023 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2024 EXPECT_EQ(96, send_codec_spec.payload_type);
2025 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002026 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002027 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002028 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002029 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002030}
2031
stefanba4c0e42016-02-04 04:12:24 -08002032class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2033 public:
2034 WebRtcVoiceEngineWithSendSideBweTest()
2035 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2036};
2037
2038TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2039 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002040 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2041 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002042 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002043 "uri", &RtpExtension::uri,
2044 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002045}
2046
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002047// Test support for audio level header extension.
2048TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002049 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002050}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002051TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002052 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002053}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002054
solenbergd4adce42016-11-17 06:26:52 -08002055// Test support for transport sequence number header extension.
2056TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2057 TestSetSendRtpHeaderExtensions(
2058 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002059}
solenbergd4adce42016-11-17 06:26:52 -08002060TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2061 TestSetRecvRtpHeaderExtensions(
2062 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002063}
2064
solenberg1ac56142015-10-13 03:58:19 -07002065// Test that we can create a channel and start sending on it.
2066TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002067 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(send_parameters_);
2069 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002070 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002071 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002072 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002073}
2074
2075// Test that a channel will send if and only if it has a source and is enabled
2076// for sending.
2077TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002078 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002079 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002080 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002081 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002082 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2083 SetAudioSend(kSsrcX, true, &fake_source_);
2084 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2085 SetAudioSend(kSsrcX, true, nullptr);
2086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002087}
2088
solenberg94218532016-06-16 10:53:22 -07002089// Test that a channel is muted/unmuted.
2090TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2091 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002092 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002093 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2094 SetAudioSend(kSsrcX, true, nullptr);
2095 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2096 SetAudioSend(kSsrcX, false, nullptr);
2097 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002098}
2099
solenberg6d6e7c52016-04-13 09:07:30 -07002100// Test that SetSendParameters() does not alter a stream's send state.
2101TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2102 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002103 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002104
2105 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002106 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002107 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002108
2109 // Changing RTP header extensions will recreate the AudioSendStream.
2110 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002111 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002112 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002113 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002114
2115 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002116 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002117 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002118
2119 // Changing RTP header extensions will recreate the AudioSendStream.
2120 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002121 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002122 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002123}
2124
solenberg1ac56142015-10-13 03:58:19 -07002125// Test that we can create a channel and start playing out on it.
2126TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002127 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002128 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002129 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002131 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002132 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002133}
2134
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135// Test that we can add and remove send streams.
2136TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2137 SetupForMultiSendStream();
2138
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002140 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141
solenbergc96df772015-10-21 13:01:53 -07002142 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002143 EXPECT_TRUE(
2144 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002145 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002147 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148 }
tfarina5237aaf2015-11-10 23:44:30 -08002149 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150
solenbergc96df772015-10-21 13:01:53 -07002151 // Delete the send streams.
2152 for (uint32_t ssrc : kSsrcs4) {
2153 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002154 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002155 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156 }
solenbergc96df772015-10-21 13:01:53 -07002157 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158}
2159
2160// Test SetSendCodecs correctly configure the codecs in all send streams.
2161TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2162 SetupForMultiSendStream();
2163
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002165 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002166 EXPECT_TRUE(
2167 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 }
2169
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002170 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002171 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002172 parameters.codecs.push_back(kIsacCodec);
2173 parameters.codecs.push_back(kCn16000Codec);
2174 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002175 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176
2177 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002178 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002179 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2180 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002181 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2182 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002183 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002184 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002185 }
2186
minyue7a973442016-10-20 03:27:12 -07002187 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002188 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002189 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002190 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002191 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2192 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002193 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2194 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002195 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002196 }
2197}
2198
2199// Test we can SetSend on all send streams correctly.
2200TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2201 SetupForMultiSendStream();
2202
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002203 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002204 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002205 EXPECT_TRUE(
2206 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002207 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002208 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002209 }
2210
2211 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002212 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002213 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002214 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002215 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216 }
2217
2218 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002219 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002220 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002222 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002223 }
2224}
2225
2226// Test we can set the correct statistics on all send streams.
2227TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2228 SetupForMultiSendStream();
2229
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002230 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002231 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002232 EXPECT_TRUE(
2233 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002234 }
solenberg85a04962015-10-27 03:35:21 -07002235
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002236 // Create a receive stream to check that none of the send streams end up in
2237 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002238 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002239
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002240 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002241 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002242 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002243 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002244
solenberg85a04962015-10-27 03:35:21 -07002245 // Check stats for the added streams.
2246 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002247 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002248 cricket::VoiceMediaInfo info;
2249 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002250
solenberg85a04962015-10-27 03:35:21 -07002251 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002252 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002253 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002254 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002255 }
hbos1acfbd22016-11-17 23:43:29 -08002256 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002257
2258 // We have added one receive stream. We should see empty stats.
2259 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002260 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002261 }
solenberg1ac56142015-10-13 03:58:19 -07002262
solenberg2100c0b2017-03-01 11:29:29 -08002263 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002264 {
2265 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002266 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002267 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002268 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002269 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002270 EXPECT_EQ(0u, info.receivers.size());
2271 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002272
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002273 // Deliver a new packet - a default receive stream should be created and we
2274 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002275 {
2276 cricket::VoiceMediaInfo info;
2277 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2278 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002279 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002280 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002281 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002282 EXPECT_EQ(1u, info.receivers.size());
2283 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002284 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002285 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002286}
2287
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002288// Test that we can add and remove receive streams, and do proper send/playout.
2289// We can receive on multiple streams while sending one stream.
2290TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002291 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
solenberg1ac56142015-10-13 03:58:19 -07002293 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002294 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002295 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002296
solenberg1ac56142015-10-13 03:58:19 -07002297 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002298 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002299 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002301
solenberg1ac56142015-10-13 03:58:19 -07002302 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002303 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304
2305 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2307 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2308 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002309
2310 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002311 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002312 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002313
2314 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002315 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2317 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002318
aleloi84ef6152016-08-04 05:28:21 -07002319 // Restart playout and make sure recv streams are played out.
2320 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002321 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2322 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323
aleloi84ef6152016-08-04 05:28:21 -07002324 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002325 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2326 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002327}
2328
wu@webrtc.org97077a32013-10-25 21:18:33 +00002329TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002330 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002331 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002332 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002333 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002334 const auto& agc_config = apm_config_.gain_controller1;
2335
2336 // Ensure default options.
2337 VerifyGainControlEnabledCorrectly();
2338 VerifyGainControlDefaultSettings();
2339
2340 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002341 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002342 EXPECT_FALSE(agc_config.enabled);
2343 send_parameters_.options.auto_gain_control = absl::nullopt;
2344
2345 send_parameters_.options.tx_agc_target_dbov = 5;
2346 SetSendParameters(send_parameters_);
2347 EXPECT_EQ(5, agc_config.target_level_dbfs);
2348 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2349
2350 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2351 SetSendParameters(send_parameters_);
2352 EXPECT_EQ(10, agc_config.compression_gain_db);
2353 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2354
2355 send_parameters_.options.tx_agc_limiter = false;
2356 SetSendParameters(send_parameters_);
2357 EXPECT_FALSE(agc_config.enable_limiter);
2358 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2359
2360 SetSendParameters(send_parameters_);
2361 // Expect all options to have been preserved.
2362 EXPECT_FALSE(agc_config.enabled);
2363 EXPECT_EQ(5, agc_config.target_level_dbfs);
2364 EXPECT_EQ(10, agc_config.compression_gain_db);
2365 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002366}
2367
minyue6b825df2016-10-31 04:08:32 -07002368TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2369 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002370 send_parameters_.options.audio_network_adaptor = true;
2371 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002372 SetSendParameters(send_parameters_);
2373 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002374 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002375}
2376
2377TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2378 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002379 send_parameters_.options.audio_network_adaptor = true;
2380 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002381 SetSendParameters(send_parameters_);
2382 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002383 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002384 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002385 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002386 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002387 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002388}
2389
2390TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2391 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002392 send_parameters_.options.audio_network_adaptor = true;
2393 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002394 SetSendParameters(send_parameters_);
2395 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002396 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002397 const int initial_num = call_.GetNumCreatedSendStreams();
2398 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002399 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002400 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2401 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002402 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002403 // AudioSendStream not expected to be recreated.
2404 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2405 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002406 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002407}
2408
michaelt6672b262017-01-11 10:17:59 -08002409class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2410 : public WebRtcVoiceEngineTestFake {
2411 public:
2412 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2413 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002414 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2415 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002416 "Enabled/") {}
2417};
2418
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002420// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002423 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424}
2425
2426TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2427 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002428 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002429 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002430 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002431 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002432 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002433 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002434 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435
solenberg85a04962015-10-27 03:35:21 -07002436 // Check stats for the added streams.
2437 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002438 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002439 cricket::VoiceMediaInfo info;
2440 EXPECT_EQ(true, channel_->GetStats(&info));
2441
2442 // We have added one send stream. We should see the stats we've set.
2443 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002444 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002445 // We have added one receive stream. We should see empty stats.
2446 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002447 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002448 }
solenberg1ac56142015-10-13 03:58:19 -07002449
solenberg566ef242015-11-06 15:34:49 -08002450 // Start sending - this affects some reported stats.
2451 {
2452 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002453 SetSend(true);
Alex Narestbbeb1092019-08-16 11:49:04 +02002454 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg566ef242015-11-06 15:34:49 -08002455 EXPECT_EQ(true, channel_->GetStats(&info));
2456 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002457 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002458 }
2459
solenberg2100c0b2017-03-01 11:29:29 -08002460 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002461 {
2462 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002463 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002464 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002465 EXPECT_EQ(true, channel_->GetStats(&info));
2466 EXPECT_EQ(1u, info.senders.size());
2467 EXPECT_EQ(0u, info.receivers.size());
2468 }
solenberg1ac56142015-10-13 03:58:19 -07002469
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002470 // Deliver a new packet - a default receive stream should be created and we
2471 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002472 {
2473 cricket::VoiceMediaInfo info;
2474 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2475 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002476 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002477 EXPECT_EQ(true, channel_->GetStats(&info));
2478 EXPECT_EQ(1u, info.senders.size());
2479 EXPECT_EQ(1u, info.receivers.size());
2480 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002481 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002482 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483}
2484
2485// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002486// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002489 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2490 EXPECT_TRUE(AddRecvStream(kSsrcY));
2491 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492}
2493
2494// Test that the local SSRC is the same on sending and receiving channels if the
2495// receive channel is created before the send channel.
2496TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002497 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002498 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002499 EXPECT_TRUE(
2500 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002501 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2502 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503}
2504
2505// Test that we can properly receive packets.
2506TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002507 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002508 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002510
Yves Gerey665174f2018-06-19 15:03:05 +02002511 EXPECT_TRUE(
2512 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513}
2514
2515// Test that we can properly receive packets on multiple streams.
2516TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002517 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002518 const uint32_t ssrc1 = 1;
2519 const uint32_t ssrc2 = 2;
2520 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002521 EXPECT_TRUE(AddRecvStream(ssrc1));
2522 EXPECT_TRUE(AddRecvStream(ssrc2));
2523 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002525 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002526 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002528 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529 }
mflodman3d7db262016-04-29 00:57:13 -07002530
2531 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2532 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2533 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2534
2535 EXPECT_EQ(s1.received_packets(), 0);
2536 EXPECT_EQ(s2.received_packets(), 0);
2537 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002538
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002539 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002540 EXPECT_EQ(s1.received_packets(), 0);
2541 EXPECT_EQ(s2.received_packets(), 0);
2542 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002543
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002545 EXPECT_EQ(s1.received_packets(), 1);
2546 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2547 EXPECT_EQ(s2.received_packets(), 0);
2548 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002549
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002551 EXPECT_EQ(s1.received_packets(), 1);
2552 EXPECT_EQ(s2.received_packets(), 1);
2553 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2554 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002555
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002557 EXPECT_EQ(s1.received_packets(), 1);
2558 EXPECT_EQ(s2.received_packets(), 1);
2559 EXPECT_EQ(s3.received_packets(), 1);
2560 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002561
mflodman3d7db262016-04-29 00:57:13 -07002562 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2563 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2564 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565}
2566
solenberg2100c0b2017-03-01 11:29:29 -08002567// Test that receiving on an unsignaled stream works (a stream is created).
2568TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002569 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002570 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002571
solenberg7e63ef02015-11-20 00:19:43 -08002572 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002573
Mirko Bonadeif859e552018-05-30 15:31:29 +02002574 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002575 EXPECT_TRUE(
2576 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002577}
2578
Seth Hampson5897a6e2018-04-03 11:16:33 -07002579// Tests that when we add a stream without SSRCs, but contains a stream_id
2580// that it is stored and its stream id is later used when the first packet
2581// arrives to properly create a receive stream with a sync label.
2582TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2583 const char kSyncLabel[] = "sync_label";
2584 EXPECT_TRUE(SetupChannel());
2585 cricket::StreamParams unsignaled_stream;
2586 unsignaled_stream.set_stream_ids({kSyncLabel});
2587 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2588 // The stream shouldn't have been created at this point because it doesn't
2589 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002590 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002591
2592 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2593
Mirko Bonadeif859e552018-05-30 15:31:29 +02002594 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002595 EXPECT_TRUE(
2596 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2597 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2598
Saurav Dasff27da52019-09-20 11:05:30 -07002599 // Remset the unsignaled stream to clear the cached parameters. If a new
Seth Hampson5897a6e2018-04-03 11:16:33 -07002600 // default unsignaled receive stream is created it will not have a sync group.
Saurav Dasff27da52019-09-20 11:05:30 -07002601 channel_->ResetUnsignaledRecvStream();
Seth Hampson5897a6e2018-04-03 11:16:33 -07002602 channel_->RemoveRecvStream(kSsrc1);
2603
2604 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2605
Mirko Bonadeif859e552018-05-30 15:31:29 +02002606 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002607 EXPECT_TRUE(
2608 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2609 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2610}
2611
solenberg2100c0b2017-03-01 11:29:29 -08002612// Test that receiving N unsignaled stream works (streams will be created), and
2613// that packets are forwarded to them all.
2614TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002615 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002616 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002617 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2618
solenberg2100c0b2017-03-01 11:29:29 -08002619 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002620 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002621 rtc::SetBE32(&packet[8], ssrc);
2622 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002623
solenberg2100c0b2017-03-01 11:29:29 -08002624 // Verify we have one new stream for each loop iteration.
2625 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002626 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2627 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002628 }
mflodman3d7db262016-04-29 00:57:13 -07002629
solenberg2100c0b2017-03-01 11:29:29 -08002630 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002631 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002632 rtc::SetBE32(&packet[8], ssrc);
2633 DeliverPacket(packet, sizeof(packet));
2634
solenbergebb349d2017-03-13 05:46:15 -07002635 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002636 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2637 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2638 }
2639
2640 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2641 constexpr uint32_t kAnotherSsrc = 667;
2642 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002643 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002644
2645 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002646 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002647 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002648 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002649 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2650 EXPECT_EQ(2, streams[i]->received_packets());
2651 }
2652 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2653 EXPECT_EQ(1, streams[i]->received_packets());
2654 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002655 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002656}
2657
solenberg2100c0b2017-03-01 11:29:29 -08002658// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002659// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002660TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002661 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002662 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002663 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2664
2665 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002666 const uint32_t signaled_ssrc = 1;
2667 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002669 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002670 EXPECT_TRUE(
2671 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002672 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002673
2674 // Note that the first unknown SSRC cannot be 0, because we only support
2675 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002676 const uint32_t unsignaled_ssrc = 7011;
2677 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002678 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002679 EXPECT_TRUE(
2680 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002681 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002682
2683 DeliverPacket(packet, sizeof(packet));
2684 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2685
2686 rtc::SetBE32(&packet[8], signaled_ssrc);
2687 DeliverPacket(packet, sizeof(packet));
2688 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002689 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002690}
2691
solenberg4904fb62017-02-17 12:01:14 -08002692// Two tests to verify that adding a receive stream with the same SSRC as a
2693// previously added unsignaled stream will only recreate underlying stream
2694// objects if the stream parameters have changed.
2695TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2696 EXPECT_TRUE(SetupChannel());
2697
2698 // Spawn unsignaled stream with SSRC=1.
2699 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002700 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002701 EXPECT_TRUE(
2702 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002703
2704 // Verify that the underlying stream object in Call is not recreated when a
2705 // stream with SSRC=1 is added.
2706 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002707 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002708 int audio_receive_stream_id = streams.front()->id();
2709 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002710 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002711 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2712}
2713
2714TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2715 EXPECT_TRUE(SetupChannel());
2716
2717 // Spawn unsignaled stream with SSRC=1.
2718 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002719 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002720 EXPECT_TRUE(
2721 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002722
2723 // Verify that the underlying stream object in Call *is* recreated when a
2724 // stream with SSRC=1 is added, and which has changed stream parameters.
2725 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002726 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002727 int audio_receive_stream_id = streams.front()->id();
2728 cricket::StreamParams stream_params;
2729 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002730 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002731 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002732 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002733 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2734}
2735
solenberg1ac56142015-10-13 03:58:19 -07002736// Test that AddRecvStream creates new stream.
2737TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002738 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002739 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740}
2741
2742// Test that after adding a recv stream, we do not decode more codecs than
2743// those previously passed into SetRecvCodecs.
2744TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002745 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002746 cricket::AudioRecvParameters parameters;
2747 parameters.codecs.push_back(kIsacCodec);
2748 parameters.codecs.push_back(kPcmuCodec);
2749 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002750 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002751 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2752 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2753 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754}
2755
2756// Test that we properly clean up any streams that were added, even if
2757// not explicitly removed.
2758TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002761 EXPECT_TRUE(AddRecvStream(1));
2762 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002763
Mirko Bonadeif859e552018-05-30 15:31:29 +02002764 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2765 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766 delete channel_;
2767 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002768 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2769 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770}
2771
Saurav Dasff27da52019-09-20 11:05:30 -07002772TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamSuccessWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002773 EXPECT_TRUE(SetupSendStream());
Saurav Dasff27da52019-09-20 11:05:30 -07002774 EXPECT_TRUE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002775}
2776
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002777TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002778 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002779 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002780 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002781}
2782
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002783// Test the InsertDtmf on default send stream as caller.
2784TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002785 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786}
2787
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002788// Test the InsertDtmf on default send stream as callee
2789TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002790 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002791}
2792
2793// Test the InsertDtmf on specified send stream as caller.
2794TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002795 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002796}
2797
2798// Test the InsertDtmf on specified send stream as callee.
2799TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002800 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
Johannes Kron9190b822018-10-29 11:22:05 +01002803// Test propagation of extmap allow mixed setting.
2804TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2805 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2806}
2807TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2808 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2809}
2810TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2811 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2812}
2813TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2814 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2815}
2816
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002818 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002819 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002820 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002821 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002822 .WillRepeatedly(Return(false));
2823 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2824 .Times(4)
2825 .WillRepeatedly(Return(false));
2826 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2827 .Times(2)
2828 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002829
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002830 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002831 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832
solenberg246b8172015-12-08 09:50:23 -08002833 // Nothing set in AudioOptions, so everything should be as default.
2834 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002835 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002836 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002837 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002838 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002839 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002840 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002841
Sam Zackrissonba502232019-01-04 10:36:48 +01002842 // Turn typing detection off.
2843 send_parameters_.options.typing_detection = false;
2844 SetSendParameters(send_parameters_);
2845 EXPECT_FALSE(IsTypingDetectionEnabled());
2846
2847 // Leave typing detection unchanged, but non-default.
2848 send_parameters_.options.typing_detection = absl::nullopt;
2849 SetSendParameters(send_parameters_);
2850 EXPECT_FALSE(IsTypingDetectionEnabled());
2851
2852 // Turn typing detection on.
2853 send_parameters_.options.typing_detection = true;
2854 SetSendParameters(send_parameters_);
2855 EXPECT_TRUE(IsTypingDetectionEnabled());
2856
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002857 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002858 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002859 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002860 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002861
2862 // Turn echo cancellation back on, with settings, and make sure
2863 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002864 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002865 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002866 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002868 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002869 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002870 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002871 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002872
Per Åhgrenf40a3402019-04-25 08:50:11 +02002873 // Restore AEC to be on to work with the following tests.
2874 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002875 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002876
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002878 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002879 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002880 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002881 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
2883 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002885 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002886 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002887 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002888
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002889 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002890 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002891 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002892 send_parameters_.options.noise_suppression = false;
2893 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002894 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002895 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002896 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002897 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002898 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899
solenberg1ac56142015-10-13 03:58:19 -07002900 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002901 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002902 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002903 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002904 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002905 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906}
2907
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002909 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002910 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2911 .Times(8)
2912 .WillRepeatedly(Return(false));
2913 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2914 .Times(8)
2915 .WillRepeatedly(Return(false));
2916 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2917 .Times(8)
2918 .WillRepeatedly(Return(false));
2919 EXPECT_CALL(adm_, RecordingIsInitialized())
2920 .Times(2)
2921 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002922 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2923 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002924 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002925
kwiberg686a8ef2016-02-26 03:00:35 -08002926 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002927 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2928 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2929 cricket::AudioOptions(),
2930 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002931 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002932 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2933 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2934 cricket::AudioOptions(),
2935 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936
2937 // Have to add a stream to make SetSend work.
2938 cricket::StreamParams stream1;
2939 stream1.ssrcs.push_back(1);
2940 channel1->AddSendStream(stream1);
2941 cricket::StreamParams stream2;
2942 stream2.ssrcs.push_back(2);
2943 channel2->AddSendStream(stream2);
2944
2945 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002946 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002947 parameters_options_all.options.echo_cancellation = true;
2948 parameters_options_all.options.auto_gain_control = true;
2949 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002952 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002953 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002954 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002955 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002956 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002957 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002958 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002960
2961 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002962 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002963 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002964 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002965 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002966 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002967 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002968 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002969 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002970 expected_options.echo_cancellation = true;
2971 expected_options.auto_gain_control = true;
2972 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002973 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002974
2975 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002976 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002977 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002980 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002981 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002982 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002983 expected_options.echo_cancellation = true;
2984 expected_options.auto_gain_control = false;
2985 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002986 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002988 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002989 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002990 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002991 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002992 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002994 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002995 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002996 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002997 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002998 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003002 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003003 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003004 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003007 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3008 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003009 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3010 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003011 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003012 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003013 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003014 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003015 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003016 expected_options.echo_cancellation = true;
3017 expected_options.auto_gain_control = false;
3018 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003019 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020}
3021
wu@webrtc.orgde305012013-10-31 15:40:38 +00003022// This test verifies DSCP settings are properly applied on voice media channel.
3023TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003024 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003025 cricket::FakeNetworkInterface network_interface;
3026 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003027 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003028 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003029
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003030 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003031
Sebastian Jansson84848f22018-11-16 10:40:36 +01003032 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3033 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3034 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003035 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003036 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3037 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3038
3039 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003040 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3041 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3042 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003043 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003044 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3045
3046 // Create a send stream to configure
3047 EXPECT_TRUE(
3048 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3049 parameters = channel->GetRtpSendParameters(kSsrcZ);
3050 ASSERT_FALSE(parameters.encodings.empty());
3051
3052 // Various priorities map to various dscp values.
3053 parameters.encodings[0].network_priority = 4.0;
3054 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003055 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003056 parameters.encodings[0].network_priority = 0.5;
3057 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3058 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3059
3060 // A bad priority does not change the dscp value.
3061 parameters.encodings[0].network_priority = 0.0;
3062 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3063 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003064
Tim Haloun6ca98362018-09-17 17:06:08 -07003065 // Packets should also self-identify their dscp in PacketOptions.
3066 const uint8_t kData[10] = {0};
3067 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003068 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003069
nisse51542be2016-02-12 02:27:06 -08003070 // Verify that setting the option to false resets the
3071 // DiffServCodePoint.
3072 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003073 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3074 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3075 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003076 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003077 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3078 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3079
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003080 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003081}
3082
solenberg4bac9c52015-10-09 02:32:53 -07003083TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003084 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003085 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003086 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003087 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003088 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003089 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3090 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3091 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003092}
3093
solenberg2100c0b2017-03-01 11:29:29 -08003094TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003095 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003096
3097 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003098 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003099 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3100
3101 // Should remember the volume "2" which will be set on new unsignaled streams,
3102 // and also set the gain to 2 on existing unsignaled streams.
3103 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3104 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3105
3106 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3107 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3108 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3109 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3110 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3111 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3112
3113 // Setting gain with SSRC=0 should affect all unsignaled streams.
3114 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003115 if (kMaxUnsignaledRecvStreams > 1) {
3116 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3117 }
solenberg2100c0b2017-03-01 11:29:29 -08003118 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3119
3120 // Setting gain on an individual stream affects only that.
3121 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003122 if (kMaxUnsignaledRecvStreams > 1) {
3123 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3124 }
solenberg2100c0b2017-03-01 11:29:29 -08003125 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003126}
3127
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003128TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3129 EXPECT_TRUE(SetupChannel());
3130 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3131 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3132
3133 cricket::StreamParams stream;
3134 stream.ssrcs.push_back(kSsrcY);
3135 EXPECT_TRUE(channel_->AddRecvStream(stream));
3136 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3137 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3138 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3139}
3140
3141TEST_F(WebRtcVoiceEngineTestFake,
3142 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3143 // Here base minimum delay is abbreviated to delay in comments for shortness.
3144 EXPECT_TRUE(SetupChannel());
3145
3146 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3147 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3148 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3149 // Check that it doesn't provide default values for unknown ssrc.
3150 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3151
3152 // Check that default value for unsignaled streams is 0.
3153 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3154
3155 // Should remember the delay 100 which will be set on new unsignaled streams,
3156 // and also set the delay to 100 on existing unsignaled streams.
3157 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3158 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3159 // Check that it doesn't provide default values for unknown ssrc.
3160 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3161
3162 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3163 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3164 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3165 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3166 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3167 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3168
3169 // Setting delay with SSRC=0 should affect all unsignaled streams.
3170 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3171 if (kMaxUnsignaledRecvStreams > 1) {
3172 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3173 }
3174 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3175
3176 // Setting delay on an individual stream affects only that.
3177 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3178 if (kMaxUnsignaledRecvStreams > 1) {
3179 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3180 }
3181 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3182 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3183 // Check that it doesn't provide default values for unknown ssrc.
3184 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3185}
3186
Seth Hampson845e8782018-03-02 11:34:10 -08003187TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003188 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003189 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003190
solenbergff976312016-03-30 23:28:51 -07003191 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003192 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003193 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003194 // Creating two channels to make sure that sync label is set properly for both
3195 // the default voice channel and following ones.
3196 EXPECT_TRUE(channel_->AddRecvStream(sp));
3197 sp.ssrcs[0] += 1;
3198 EXPECT_TRUE(channel_->AddRecvStream(sp));
3199
Mirko Bonadeif859e552018-05-30 15:31:29 +02003200 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003201 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003202 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003203 << "SyncGroup should be set based on stream id";
3204 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003205 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003206 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003207}
3208
solenberg3a941542015-11-16 07:34:50 -08003209// TODO(solenberg): Remove, once recv streams are configured through Call.
3210// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003211TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003212 // Test that setting the header extensions results in the expected state
3213 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003214 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003215 ssrcs.push_back(223);
3216 ssrcs.push_back(224);
3217
solenbergff976312016-03-30 23:28:51 -07003218 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003219 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003220 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003221 EXPECT_TRUE(
3222 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003223 }
3224
Mirko Bonadeif859e552018-05-30 15:31:29 +02003225 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003226 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003227 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003228 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003229 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003230 }
3231
3232 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003233 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003234 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003235 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003236 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003237 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003238 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003239 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003240 EXPECT_NE(nullptr, s);
3241 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003242 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3243 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244 for (const auto& s_ext : s_exts) {
3245 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003246 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003247 }
3248 }
3249 }
3250 }
3251
3252 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003253 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003254 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003255 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003256 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003257 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003259}
3260
3261TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3262 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003263 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003264 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003265 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003266 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3267 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003269 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003270
solenbergff976312016-03-30 23:28:51 -07003271 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 cricket::WebRtcVoiceMediaChannel* media_channel =
3273 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003274 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 EXPECT_TRUE(media_channel->AddRecvStream(
3276 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3277
Mirko Bonadeif859e552018-05-30 15:31:29 +02003278 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003279 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003280 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003281 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003282 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003283 EXPECT_EQ(1, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003284}
Minyue2013aec2015-05-13 14:14:42 +02003285
solenberg0a617e22015-10-20 15:49:38 -07003286// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003287// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003288TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003289 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003290 EXPECT_TRUE(AddRecvStream(kSsrcY));
3291 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003292 EXPECT_TRUE(
3293 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003294 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3295 EXPECT_TRUE(AddRecvStream(kSsrcW));
3296 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003297}
3298
solenberg7602aab2016-11-14 11:30:07 -08003299TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3300 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003301 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003302 EXPECT_TRUE(
3303 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003304 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3305 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3306 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003307 EXPECT_TRUE(
3308 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003309 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3310 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003311}
stefan658910c2015-09-03 05:48:32 -07003312
deadbeef884f5852016-01-15 09:20:04 -08003313TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003314 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003315 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3316 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003317
3318 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003319 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3320 EXPECT_TRUE(AddRecvStream(kSsrcX));
3321 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003322
3323 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003324 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3325 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003326
3327 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003328 channel_->SetRawAudioSink(kSsrcX, nullptr);
3329 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003330}
3331
solenberg2100c0b2017-03-01 11:29:29 -08003332TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003333 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003334 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3335 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003336 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3337 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003338
3339 // Should be able to set a default sink even when no stream exists.
3340 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3341
solenberg2100c0b2017-03-01 11:29:29 -08003342 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3343 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003344 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003345 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003346
3347 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003348 channel_->SetRawAudioSink(kSsrc0, nullptr);
3349 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003350
3351 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003352 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3353 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003354
3355 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003356 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003357 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003358 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3359
3360 // Spawn another unsignaled stream - it should be assigned the default sink
3361 // and the previous unsignaled stream should lose it.
3362 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3363 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3364 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3365 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003366 if (kMaxUnsignaledRecvStreams > 1) {
3367 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3368 }
solenberg2100c0b2017-03-01 11:29:29 -08003369 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3370
3371 // Reset the default sink - the second unsignaled stream should lose it.
3372 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003373 if (kMaxUnsignaledRecvStreams > 1) {
3374 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3375 }
solenberg2100c0b2017-03-01 11:29:29 -08003376 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3377
3378 // Try setting the default sink while two streams exists.
3379 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003380 if (kMaxUnsignaledRecvStreams > 1) {
3381 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3382 }
solenberg2100c0b2017-03-01 11:29:29 -08003383 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3384
3385 // Try setting the sink for the first unsignaled stream using its known SSRC.
3386 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003387 if (kMaxUnsignaledRecvStreams > 1) {
3388 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3389 }
solenberg2100c0b2017-03-01 11:29:29 -08003390 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003391 if (kMaxUnsignaledRecvStreams > 1) {
3392 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3393 }
deadbeef884f5852016-01-15 09:20:04 -08003394}
3395
skvlad7a43d252016-03-22 15:32:27 -07003396// Test that, just like the video channel, the voice channel communicates the
3397// network state to the call.
3398TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003399 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003400
3401 EXPECT_EQ(webrtc::kNetworkUp,
3402 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3403 EXPECT_EQ(webrtc::kNetworkUp,
3404 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3405
3406 channel_->OnReadyToSend(false);
3407 EXPECT_EQ(webrtc::kNetworkDown,
3408 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3409 EXPECT_EQ(webrtc::kNetworkUp,
3410 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3411
3412 channel_->OnReadyToSend(true);
3413 EXPECT_EQ(webrtc::kNetworkUp,
3414 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3415 EXPECT_EQ(webrtc::kNetworkUp,
3416 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3417}
3418
aleloi18e0b672016-10-04 02:45:47 -07003419// Test that playout is still started after changing parameters
3420TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3421 SetupRecvStream();
3422 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003423 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003424
3425 // Changing RTP header extensions will recreate the AudioReceiveStream.
3426 cricket::AudioRecvParameters parameters;
3427 parameters.extensions.push_back(
3428 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3429 channel_->SetRecvParameters(parameters);
3430
solenberg2100c0b2017-03-01 11:29:29 -08003431 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003432}
3433
Zhi Huangfa266ef2017-12-13 10:27:46 -08003434// Tests when GetSources is called with non-existing ssrc, it will return an
3435// empty list of RtpSource without crashing.
3436TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3437 // Setup an recv stream with |kSsrcX|.
3438 SetupRecvStream();
3439 cricket::WebRtcVoiceMediaChannel* media_channel =
3440 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3441 // Call GetSources with |kSsrcY| which doesn't exist.
3442 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3443 EXPECT_EQ(0u, sources.size());
3444}
3445
stefan658910c2015-09-03 05:48:32 -07003446// Tests that the library initializes and shuts down properly.
3447TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003448 // If the VoiceEngine wants to gather available codecs early, that's fine but
3449 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003450 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3451 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003452 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003453 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003454 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003455 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003456 task_queue_factory.get(), &adm,
3457 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003458 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003459 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003460 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003461 webrtc::Call::Config call_config(&event_log);
3462 call_config.task_queue_factory = task_queue_factory.get();
3463 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003464 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3465 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3466 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003467 EXPECT_TRUE(channel != nullptr);
3468 delete channel;
solenbergff976312016-03-30 23:28:51 -07003469}
stefan658910c2015-09-03 05:48:32 -07003470
solenbergff976312016-03-30 23:28:51 -07003471// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003472TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003473 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3474 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003475 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003476 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003477 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003478 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003479 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003480 {
peaha9cc40b2017-06-29 08:32:09 -07003481 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003482 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003483 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003484 task_queue_factory.get(), &adm,
3485 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003486 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003487 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003488 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003489 webrtc::Call::Config call_config(&event_log);
3490 call_config.task_queue_factory = task_queue_factory.get();
3491 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003492 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3493 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3494 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003495 EXPECT_TRUE(channel != nullptr);
3496 delete channel;
3497 }
stefan658910c2015-09-03 05:48:32 -07003498}
3499
ossu20a4b3f2017-04-27 02:08:52 -07003500// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3501TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003502 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3503 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003504 // TODO(ossu): Why are the payload types of codecs with non-static payload
3505 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003506 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003507 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003508 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003509 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003510 task_queue_factory.get(), &adm,
3511 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003512 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003513 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003514 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003515 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003516 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003517 (clockrate == 0 || codec.clockrate == clockrate);
3518 };
3519 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003520 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003521 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003522 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003523 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003524 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003525 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003526 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003527 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003528 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003529 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003530 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003531 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3532 // Remove these checks once both send and receive side assigns payload
3533 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003534 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003535 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003536 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003537 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003538 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003539 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003540 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003541 EXPECT_EQ(111, codec.id);
3542 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3543 EXPECT_EQ("10", codec.params.find("minptime")->second);
3544 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3545 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003546 }
3547 }
stefan658910c2015-09-03 05:48:32 -07003548}
3549
3550// Tests that VoE supports at least 32 channels
3551TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003552 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3553 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003554 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003555 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003556 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003557 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003558 task_queue_factory.get(), &adm,
3559 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003560 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003561 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003562 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003563 webrtc::Call::Config call_config(&event_log);
3564 call_config.task_queue_factory = task_queue_factory.get();
3565 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
stefan658910c2015-09-03 05:48:32 -07003566
3567 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003568 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003569 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003570 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3571 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3572 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003573 if (!channel)
3574 break;
stefan658910c2015-09-03 05:48:32 -07003575 channels[num_channels++] = channel;
3576 }
3577
Mirko Bonadeif859e552018-05-30 15:31:29 +02003578 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003579 EXPECT_EQ(expected, num_channels);
3580
3581 while (num_channels > 0) {
3582 delete channels[--num_channels];
3583 }
stefan658910c2015-09-03 05:48:32 -07003584}
3585
3586// Test that we set our preferred codecs properly.
3587TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003588 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3589 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003590 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3591 // - Check that our builtin codecs are usable by Channel.
3592 // - The codecs provided by the engine is usable by Channel.
3593 // It does not check that the codecs in the RecvParameters are actually
3594 // what we sent in - though it's probably reasonable to expect so, if
3595 // SetRecvParameters returns true.
3596 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003597 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003598 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003599 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003600 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003601 task_queue_factory.get(), &adm,
3602 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003603 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003604 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003605 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003606 webrtc::Call::Config call_config(&event_log);
3607 call_config.task_queue_factory = task_queue_factory.get();
3608 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
nisse51542be2016-02-12 02:27:06 -08003609 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003610 cricket::AudioOptions(),
3611 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003612 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003613 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003614 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003615}
ossu9def8002017-02-09 05:14:32 -08003616
3617TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3618 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003619 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3620 {48000, 2, 16000, 10000, 20000}};
3621 spec1.info.allow_comfort_noise = false;
3622 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003623 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003624 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3625 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003626 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003627 specs.push_back(webrtc::AudioCodecSpec{
3628 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3629 {16000, 1, 13300}});
3630 specs.push_back(
3631 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3632 specs.push_back(
3633 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003634
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003635 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3636 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003637 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3638 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3639 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003640 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003641 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003642 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003643 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003644
peaha9cc40b2017-06-29 08:32:09 -07003645 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003646 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003647 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3648 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003649 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003650 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003651 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003652 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003653
3654 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3655 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003656 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3657 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3658 if (codecs.size() > index)
3659 return codecs[index];
3660 return missing_codec;
3661 };
ossu9def8002017-02-09 05:14:32 -08003662
3663 // Ensure the general codecs are generated first and in order.
3664 for (size_t i = 0; i != specs.size(); ++i) {
3665 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3666 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3667 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3668 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3669 }
3670
3671 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003672 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003673 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3674 for (size_t i = 0; i != codecs.size(); ++i) {
3675 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003676 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003677 codec.clockrate == format.clockrate_hz &&
3678 codec.channels == format.num_channels) {
3679 return rtc::checked_cast<int>(i);
3680 }
3681 }
3682 return -1;
3683 };
ossu9def8002017-02-09 05:14:32 -08003684
3685 // Ensure all supplementary codecs are generated last. Their internal ordering
3686 // is not important.
3687 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3688 const int num_specs = static_cast<int>(specs.size());
3689 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3690 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3691 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3692 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3693 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3694 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3695 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3696}