blob: 8fac2a1f927e6f13fd88791e984527458a421442 [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;
569 stats.bytes_sent = 345;
570 stats.packets_sent = 678;
571 stats.packets_lost = 9012;
572 stats.fraction_lost = 34.56f;
573 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100574 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700575 stats.jitter_ms = 12;
576 stats.rtt_ms = 345;
577 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100578 stats.apm_statistics.delay_median_ms = 234;
579 stats.apm_statistics.delay_standard_deviation_ms = 567;
580 stats.apm_statistics.echo_return_loss = 890;
581 stats.apm_statistics.echo_return_loss_enhancement = 1234;
582 stats.apm_statistics.residual_echo_likelihood = 0.432f;
583 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100584 stats.ana_statistics.bitrate_action_counter = 321;
585 stats.ana_statistics.channel_action_counter = 432;
586 stats.ana_statistics.dtx_action_counter = 543;
587 stats.ana_statistics.fec_action_counter = 654;
588 stats.ana_statistics.frame_length_increase_counter = 765;
589 stats.ana_statistics.frame_length_decrease_counter = 876;
590 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700591 stats.typing_noise_detected = true;
592 return stats;
593 }
594 void SetAudioSendStreamStats() {
595 for (auto* s : call_.GetAudioSendStreams()) {
596 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200597 }
solenberg85a04962015-10-27 03:35:21 -0700598 }
solenberg566ef242015-11-06 15:34:49 -0800599 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
600 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700601 const auto stats = GetAudioSendStreamStats();
602 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
603 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
604 EXPECT_EQ(info.packets_sent, stats.packets_sent);
605 EXPECT_EQ(info.packets_lost, stats.packets_lost);
606 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
607 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800608 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700609 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
610 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
611 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100612 EXPECT_EQ(info.apm_statistics.delay_median_ms,
613 stats.apm_statistics.delay_median_ms);
614 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
615 stats.apm_statistics.delay_standard_deviation_ms);
616 EXPECT_EQ(info.apm_statistics.echo_return_loss,
617 stats.apm_statistics.echo_return_loss);
618 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
619 stats.apm_statistics.echo_return_loss_enhancement);
620 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
621 stats.apm_statistics.residual_echo_likelihood);
622 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
623 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700624 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
625 stats.ana_statistics.bitrate_action_counter);
626 EXPECT_EQ(info.ana_statistics.channel_action_counter,
627 stats.ana_statistics.channel_action_counter);
628 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
629 stats.ana_statistics.dtx_action_counter);
630 EXPECT_EQ(info.ana_statistics.fec_action_counter,
631 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700632 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
633 stats.ana_statistics.frame_length_increase_counter);
634 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
635 stats.ana_statistics.frame_length_decrease_counter);
636 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
637 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800638 EXPECT_EQ(info.typing_noise_detected,
639 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700640 }
641
642 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
643 webrtc::AudioReceiveStream::Stats stats;
644 stats.remote_ssrc = 123;
645 stats.bytes_rcvd = 456;
646 stats.packets_rcvd = 768;
647 stats.packets_lost = 101;
solenberg85a04962015-10-27 03:35:21 -0700648 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100649 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700650 stats.jitter_ms = 901;
651 stats.jitter_buffer_ms = 234;
652 stats.jitter_buffer_preferred_ms = 567;
653 stats.delay_estimate_ms = 890;
654 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700655 stats.total_samples_received = 5678901;
656 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200657 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200658 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100659 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700660 stats.expand_rate = 5.67f;
661 stats.speech_expand_rate = 8.90f;
662 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200663 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700664 stats.accelerate_rate = 4.56f;
665 stats.preemptive_expand_rate = 7.89f;
666 stats.decoding_calls_to_silence_generator = 12;
667 stats.decoding_calls_to_neteq = 345;
668 stats.decoding_normal = 67890;
669 stats.decoding_plc = 1234;
Alex Narest5b5d97c2019-08-07 18:15:08 +0200670 stats.decoding_codec_plc = 1236;
solenberg85a04962015-10-27 03:35:21 -0700671 stats.decoding_cng = 5678;
672 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700673 stats.decoding_muted_output = 3456;
674 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200675 return stats;
676 }
677 void SetAudioReceiveStreamStats() {
678 for (auto* s : call_.GetAudioReceiveStreams()) {
679 s->SetStats(GetAudioReceiveStreamStats());
680 }
681 }
682 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700683 const auto stats = GetAudioReceiveStreamStats();
684 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
685 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200686 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
687 stats.packets_rcvd);
688 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
689 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700690 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800691 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
694 stats.jitter_buffer_ms);
695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700696 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
698 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700699 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700700 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
701 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200702 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200703 EXPECT_EQ(info.jitter_buffer_delay_seconds,
704 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100705 EXPECT_EQ(info.jitter_buffer_emitted_count,
706 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700707 EXPECT_EQ(info.expand_rate, stats.expand_rate);
708 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
709 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200710 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700711 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
712 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200713 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700714 stats.decoding_calls_to_silence_generator);
715 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
716 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
717 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
Alex Narest5b5d97c2019-08-07 18:15:08 +0200718 EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
solenberg85a04962015-10-27 03:35:21 -0700719 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
720 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700721 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700722 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200723 }
hbos1acfbd22016-11-17 23:43:29 -0800724 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
725 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
726 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
727 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
728 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
729 codec.ToCodecParameters());
730 }
731 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
732 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
733 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
734 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
735 codec.ToCodecParameters());
736 }
737 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200738
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100739 void VerifyGainControlEnabledCorrectly() {
740 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
741 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
742 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
743 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
744 }
745
746 void VerifyGainControlDefaultSettings() {
747 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
748 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
749 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
750 }
751
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200752 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100753 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200754 }
755
peah8271d042016-11-22 07:24:52 -0800756 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100757 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800758 }
759
Sam Zackrissonba502232019-01-04 10:36:48 +0100760 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100761 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100762 }
763
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000764 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100765 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700766 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700767 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800768 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200769 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700770 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700771 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200772 cricket::AudioSendParameters send_parameters_;
773 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800774 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700775 webrtc::AudioProcessing::Config apm_config_;
776
stefanba4c0e42016-02-04 04:12:24 -0800777 private:
778 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779};
780
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100782TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700783 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784}
785
solenberg31fec402016-05-06 02:13:12 -0700786// Test that we can add a send stream and that it has the correct defaults.
787TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
788 EXPECT_TRUE(SetupChannel());
789 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800790 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
791 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
792 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700793 EXPECT_EQ("", config.rtp.c_name);
794 EXPECT_EQ(0u, config.rtp.extensions.size());
795 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
796 config.send_transport);
797}
798
799// Test that we can add a receive stream and that it has the correct defaults.
800TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
801 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800802 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700803 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800804 GetRecvStreamConfig(kSsrcX);
805 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700806 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
807 EXPECT_FALSE(config.rtp.transport_cc);
808 EXPECT_EQ(0u, config.rtp.extensions.size());
809 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
810 config.rtcp_send_transport);
811 EXPECT_EQ("", config.sync_group);
812}
813
stefanba4c0e42016-02-04 04:12:24 -0800814TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700815 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800816 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100817 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800818 if (codec.name == "opus") {
819 EXPECT_TRUE(HasTransportCc(codec));
820 opus_found = true;
821 }
822 }
823 EXPECT_TRUE(opus_found);
824}
825
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826// Test that we set our inbound codecs properly, including changing PT.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800832 parameters.codecs.push_back(kTelephoneEventCodec1);
833 parameters.codecs.push_back(kTelephoneEventCodec2);
834 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200835 parameters.codecs[2].id = 126;
836 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800837 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700838 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
839 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
840 {{0, {"PCMU", 8000, 1}},
841 {106, {"ISAC", 16000, 1}},
842 {126, {"telephone-event", 8000, 1}},
843 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844}
845
846// Test that we fail to set an unknown inbound codec.
847TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700848 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200849 cricket::AudioRecvParameters parameters;
850 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700851 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that we fail if we have duplicate types in the inbound list.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kCn16000Codec);
861 parameters.codecs[1].id = kIsacCodec.id;
862 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
865// Test that we can decode OPUS without stereo parameters.
866TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700867 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200868 cricket::AudioRecvParameters parameters;
869 parameters.codecs.push_back(kIsacCodec);
870 parameters.codecs.push_back(kPcmuCodec);
871 parameters.codecs.push_back(kOpusCodec);
872 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800873 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700874 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
875 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
876 {{0, {"PCMU", 8000, 1}},
877 {103, {"ISAC", 16000, 1}},
878 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000879}
880
881// Test that we can decode OPUS with stereo = 0.
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
886 parameters.codecs.push_back(kPcmuCodec);
887 parameters.codecs.push_back(kOpusCodec);
888 parameters.codecs[2].params["stereo"] = "0";
889 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800890 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700891 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
892 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
893 {{0, {"PCMU", 8000, 1}},
894 {103, {"ISAC", 16000, 1}},
895 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
898// Test that we can decode OPUS with stereo = 1.
899TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700900 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200901 cricket::AudioRecvParameters parameters;
902 parameters.codecs.push_back(kIsacCodec);
903 parameters.codecs.push_back(kPcmuCodec);
904 parameters.codecs.push_back(kOpusCodec);
905 parameters.codecs[2].params["stereo"] = "1";
906 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800907 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700908 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
909 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
910 {{0, {"PCMU", 8000, 1}},
911 {103, {"ISAC", 16000, 1}},
912 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913}
914
915// Test that changes to recv codecs are applied to all streams.
916TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700917 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 cricket::AudioRecvParameters parameters;
919 parameters.codecs.push_back(kIsacCodec);
920 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800921 parameters.codecs.push_back(kTelephoneEventCodec1);
922 parameters.codecs.push_back(kTelephoneEventCodec2);
923 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 parameters.codecs[2].id = 126;
925 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700926 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
927 EXPECT_TRUE(AddRecvStream(ssrc));
928 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
929 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
930 {{0, {"PCMU", 8000, 1}},
931 {106, {"ISAC", 16000, 1}},
932 {126, {"telephone-event", 8000, 1}},
933 {107, {"telephone-event", 32000, 1}}})));
934 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935}
936
937TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 cricket::AudioRecvParameters parameters;
940 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800941 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
solenberg2100c0b2017-03-01 11:29:29 -0800944 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200945 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800946 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947}
948
949// Test that we can apply the same set of codecs again while playing.
950TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952 cricket::AudioRecvParameters parameters;
953 parameters.codecs.push_back(kIsacCodec);
954 parameters.codecs.push_back(kCn16000Codec);
955 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700956 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
deadbeefcb383672017-04-26 16:28:42 -0700959 // Remapping a payload type to a different codec should fail.
960 parameters.codecs[0] = kOpusCodec;
961 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800963 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
966// Test that we can add a codec while playing.
967TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200969 cricket::AudioRecvParameters parameters;
970 parameters.codecs.push_back(kIsacCodec);
971 parameters.codecs.push_back(kCn16000Codec);
972 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700973 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 parameters.codecs.push_back(kOpusCodec);
976 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800977 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978}
979
deadbeefcb383672017-04-26 16:28:42 -0700980// Test that we accept adding the same codec with a different payload type.
981// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
982TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
983 EXPECT_TRUE(SetupRecvStream());
984 cricket::AudioRecvParameters parameters;
985 parameters.codecs.push_back(kIsacCodec);
986 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
987
988 ++parameters.codecs[0].id;
989 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
990}
991
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700993 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000995 // Test that when autobw is enabled, bitrate is kept as the default
996 // value. autobw is enabled for the following tests because the target
997 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
999 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001000 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001003 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
ossu20a4b3f2017-04-27 02:08:52 -07001005 // opus, default bitrate == 32000 in mono.
1006 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007}
1008
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001009TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001010 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001013 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1014 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001015 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001018 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1019 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1020 // Rates above the max (510000) should be capped.
1021 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022}
1023
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001024TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001025 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001026
1027 // Test that we can only set a maximum bitrate for a fixed-rate codec
1028 // if it's bigger than the fixed rate.
1029
1030 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001031 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1032 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1033 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1034 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1035 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1036 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001038}
1039
1040TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001041 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001042 const int kDesiredBitrate = 128000;
1043 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001044 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001046 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001047
Yves Gerey665174f2018-06-19 15:03:05 +02001048 EXPECT_TRUE(
1049 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001050
solenberg2100c0b2017-03-01 11:29:29 -08001051 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001052}
1053
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054// Test that bitrate cannot be set for CBR codecs.
1055// Bitrate is ignored if it is higher than the fixed bitrate.
1056// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001057TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001058 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059
1060 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001061 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001062 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001063
1064 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001065 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001067
1068 send_parameters_.max_bandwidth_bps = 128;
1069 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071}
1072
skvlade0d46372016-04-07 22:59:22 -07001073// Test that the per-stream bitrate limit and the global
1074// bitrate limit both apply.
1075TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1076 EXPECT_TRUE(SetupSendStream());
1077
ossu20a4b3f2017-04-27 02:08:52 -07001078 // opus, default bitrate == 32000.
1079 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001080 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1081 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1082 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1083
1084 // CBR codecs allow both maximums to exceed the bitrate.
1085 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1086 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1087 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1088 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1089
1090 // CBR codecs don't allow per stream maximums to be too low.
1091 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1093}
1094
1095// Test that an attempt to set RtpParameters for a stream that does not exist
1096// fails.
1097TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1098 EXPECT_TRUE(SetupChannel());
1099 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001100 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001101 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001102
1103 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001104 EXPECT_FALSE(
1105 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001106}
1107
1108TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001109 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001110 // This test verifies that setting RtpParameters succeeds only if
1111 // the structure contains exactly one encoding.
1112 // TODO(skvlad): Update this test when we start supporting setting parameters
1113 // for each encoding individually.
1114
1115 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001116 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001117 // Two or more encodings should result in failure.
1118 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001119 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001120 // Zero encodings should also fail.
1121 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001122 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001123}
1124
1125// Changing the SSRC through RtpParameters is not allowed.
1126TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1127 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001128 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001129 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001130 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001131}
1132
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001133// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001134// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001135TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1136 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001137 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001138 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001140 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001141 ASSERT_EQ(1u, parameters.encodings.size());
1142 ASSERT_TRUE(parameters.encodings[0].active);
1143 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001144 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001145 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146
1147 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001148 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001149 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001150 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001151 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001152 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001153}
1154
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155// Test that SetRtpSendParameters configures the correct encoding channel for
1156// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001157TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1158 SetupForMultiSendStream();
1159 // Create send streams.
1160 for (uint32_t ssrc : kSsrcs4) {
1161 EXPECT_TRUE(
1162 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1163 }
1164 // Configure one stream to be limited by the stream config, another to be
1165 // limited by the global max, and the third one with no per-stream limit
1166 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001167 SetGlobalMaxBitrate(kOpusCodec, 32000);
1168 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1169 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001170 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1171
ossu20a4b3f2017-04-27 02:08:52 -07001172 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1173 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1174 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001175
1176 // Remove the global cap; the streams should switch to their respective
1177 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001178 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001179 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1180 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1181 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001182}
1183
Tim Haloun648d28a2018-10-18 16:52:22 -07001184// RTCRtpEncodingParameters.network_priority must be one of a few values
1185// derived from the default priority, corresponding to very-low, low, medium,
1186// or high.
1187TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1188 EXPECT_TRUE(SetupSendStream());
1189 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1190 EXPECT_EQ(1UL, parameters.encodings.size());
1191 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1192 parameters.encodings[0].network_priority);
1193
1194 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1195 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1196 for (auto it : good_values) {
1197 parameters.encodings[0].network_priority = it;
1198 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1199 }
1200 for (auto it : bad_values) {
1201 parameters.encodings[0].network_priority = it;
1202 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1203 }
1204}
1205
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001206// Test that GetRtpSendParameters returns the currently configured codecs.
1207TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001208 EXPECT_TRUE(SetupSendStream());
1209 cricket::AudioSendParameters parameters;
1210 parameters.codecs.push_back(kIsacCodec);
1211 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001212 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001213
solenberg2100c0b2017-03-01 11:29:29 -08001214 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001215 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001216 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1217 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218}
1219
Florent Castellidacec712018-05-24 16:24:21 +02001220// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1221TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1222 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1223 params.cname = "rtcpcname";
1224 EXPECT_TRUE(SetupSendStream(params));
1225
1226 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1227 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1228}
1229
Florent Castelliabe301f2018-06-12 18:33:49 +02001230TEST_F(WebRtcVoiceEngineTestFake,
1231 DetectRtpSendParameterHeaderExtensionsChange) {
1232 EXPECT_TRUE(SetupSendStream());
1233
1234 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1235 rtp_parameters.header_extensions.emplace_back();
1236
1237 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1238
1239 webrtc::RTCError result =
1240 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1241 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1242}
1243
deadbeefcb443432016-12-12 11:12:36 -08001244// Test that GetRtpSendParameters returns an SSRC.
1245TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1246 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001247 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001248 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001249 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001250}
1251
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001252// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001253TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001254 EXPECT_TRUE(SetupSendStream());
1255 cricket::AudioSendParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001258 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001259
solenberg2100c0b2017-03-01 11:29:29 -08001260 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001261
1262 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001263 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001265 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001266 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1267 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001268}
1269
minyuececec102017-03-27 13:04:25 -07001270// Test that max_bitrate_bps in send stream config gets updated correctly when
1271// SetRtpSendParameters is called.
1272TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1273 webrtc::test::ScopedFieldTrials override_field_trials(
1274 "WebRTC-Audio-SendSideBwe/Enabled/");
1275 EXPECT_TRUE(SetupSendStream());
1276 cricket::AudioSendParameters send_parameters;
1277 send_parameters.codecs.push_back(kOpusCodec);
1278 SetSendParameters(send_parameters);
1279
1280 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1281 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1282 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1283
1284 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001285 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001286 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001287
1288 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1289 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1290}
1291
Seth Hampson24722b32017-12-22 09:36:42 -08001292// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1293// a value <= 0, setting the parameters returns false.
1294TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1295 EXPECT_TRUE(SetupSendStream());
1296 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1297 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1298 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1299 rtp_parameters.encodings[0].bitrate_priority);
1300
1301 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001302 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001303 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001304 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001305}
1306
1307// Test that the bitrate_priority in the send stream config gets updated when
1308// SetRtpSendParameters is set for the VoiceMediaChannel.
1309TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1310 EXPECT_TRUE(SetupSendStream());
1311 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1312
1313 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1314 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1315 rtp_parameters.encodings[0].bitrate_priority);
1316 double new_bitrate_priority = 2.0;
1317 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001318 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001319
1320 // The priority should get set for both the audio channel's rtp parameters
1321 // and the audio send stream's audio config.
1322 EXPECT_EQ(
1323 new_bitrate_priority,
1324 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1325 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1326}
1327
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001328// Test that GetRtpReceiveParameters returns the currently configured codecs.
1329TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1330 EXPECT_TRUE(SetupRecvStream());
1331 cricket::AudioRecvParameters parameters;
1332 parameters.codecs.push_back(kIsacCodec);
1333 parameters.codecs.push_back(kPcmuCodec);
1334 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1335
1336 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001337 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001338 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1339 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1340 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1341}
1342
deadbeefcb443432016-12-12 11:12:36 -08001343// Test that GetRtpReceiveParameters returns an SSRC.
1344TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1345 EXPECT_TRUE(SetupRecvStream());
1346 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001347 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001348 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001349 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001350}
1351
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001352// Test that if we set/get parameters multiple times, we get the same results.
1353TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1354 EXPECT_TRUE(SetupRecvStream());
1355 cricket::AudioRecvParameters parameters;
1356 parameters.codecs.push_back(kIsacCodec);
1357 parameters.codecs.push_back(kPcmuCodec);
1358 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1359
1360 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001361 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001362
1363 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001364 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001365
1366 // ... And this shouldn't change the params returned by
1367 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001368 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1369 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001370}
1371
deadbeef3bc15102017-04-20 19:25:07 -07001372// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1373// aren't signaled. It should return an empty "RtpEncodingParameters" when
1374// configured to receive an unsignaled stream and no packets have been received
1375// yet, and start returning the SSRC once a packet has been received.
1376TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1377 ASSERT_TRUE(SetupChannel());
1378 // Call necessary methods to configure receiving a default stream as
1379 // soon as it arrives.
1380 cricket::AudioRecvParameters parameters;
1381 parameters.codecs.push_back(kIsacCodec);
1382 parameters.codecs.push_back(kPcmuCodec);
1383 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1384
1385 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1386 // stream. Should return nothing.
1387 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1388
1389 // Set a sink for an unsignaled stream.
1390 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1391 // Value of "0" means "unsignaled stream".
1392 channel_->SetRawAudioSink(0, std::move(fake_sink));
1393
1394 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1395 // in this method means "unsignaled stream".
1396 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1397 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1398 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1399
1400 // Receive PCMU packet (SSRC=1).
1401 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1402
1403 // The |ssrc| member should still be unset.
1404 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1405 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1406 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1407}
1408
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409// Test that we apply codecs properly.
1410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kIsacCodec);
1414 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001415 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001417 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001419 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1420 EXPECT_EQ(96, send_codec_spec.payload_type);
1421 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1422 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1423 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001424 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001425 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426}
1427
ossu20a4b3f2017-04-27 02:08:52 -07001428// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1429// AudioSendStream.
1430TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001431 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 cricket::AudioSendParameters parameters;
1433 parameters.codecs.push_back(kIsacCodec);
1434 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001435 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 parameters.codecs[0].id = 96;
1437 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001438 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001441 // Calling SetSendCodec again with same codec which is already set.
1442 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001444 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1448// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001449
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001450// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001452 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001453 cricket::AudioSendParameters parameters;
1454 parameters.codecs.push_back(kOpusCodec);
1455 parameters.codecs[0].bitrate = 0;
1456 parameters.codecs[0].clockrate = 50000;
1457 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458}
1459
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001460// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].bitrate = 0;
1466 parameters.codecs[0].channels = 0;
1467 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468}
1469
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001470// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001472 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 cricket::AudioSendParameters parameters;
1474 parameters.codecs.push_back(kOpusCodec);
1475 parameters.codecs[0].bitrate = 0;
1476 parameters.codecs[0].channels = 0;
1477 parameters.codecs[0].params["stereo"] = "1";
1478 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479}
1480
1481// Test that if channel is 1 for opus and there's no stereo, we fail.
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001483 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 cricket::AudioSendParameters parameters;
1485 parameters.codecs.push_back(kOpusCodec);
1486 parameters.codecs[0].bitrate = 0;
1487 parameters.codecs[0].channels = 1;
1488 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001489}
1490
1491// Test that if channel is 1 for opus and stereo=0, we fail.
1492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001493 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001494 cricket::AudioSendParameters parameters;
1495 parameters.codecs.push_back(kOpusCodec);
1496 parameters.codecs[0].bitrate = 0;
1497 parameters.codecs[0].channels = 1;
1498 parameters.codecs[0].params["stereo"] = "0";
1499 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001500}
1501
1502// Test that if channel is 1 for opus and stereo=1, we fail.
1503TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001504 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001505 cricket::AudioSendParameters parameters;
1506 parameters.codecs.push_back(kOpusCodec);
1507 parameters.codecs[0].bitrate = 0;
1508 parameters.codecs[0].channels = 1;
1509 parameters.codecs[0].params["stereo"] = "1";
1510 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511}
1512
ossu20a4b3f2017-04-27 02:08:52 -07001513// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001515 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001516 cricket::AudioSendParameters parameters;
1517 parameters.codecs.push_back(kOpusCodec);
1518 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001519 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001520 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001521}
1522
ossu20a4b3f2017-04-27 02:08:52 -07001523// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001525 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001526 cricket::AudioSendParameters parameters;
1527 parameters.codecs.push_back(kOpusCodec);
1528 parameters.codecs[0].bitrate = 0;
1529 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001531 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532}
1533
ossu20a4b3f2017-04-27 02:08:52 -07001534// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001540 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001543 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001544
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001546 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001547 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001548}
1549
ossu20a4b3f2017-04-27 02:08:52 -07001550// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].bitrate = 0;
1556 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001558 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
ossu20a4b3f2017-04-27 02:08:52 -07001561// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001567 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001568 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001569 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001570 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001571
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001572 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001574 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001575}
1576
ossu20a4b3f2017-04-27 02:08:52 -07001577// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001584 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1585 EXPECT_EQ(111, spec.payload_type);
1586 EXPECT_EQ(96000, spec.target_bitrate_bps);
1587 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001588 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001589 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001590}
1591
ossu20a4b3f2017-04-27 02:08:52 -07001592// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001594 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001595 cricket::AudioSendParameters parameters;
1596 parameters.codecs.push_back(kOpusCodec);
1597 parameters.codecs[0].bitrate = 30000;
1598 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001600 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601}
1602
ossu20a4b3f2017-04-27 02:08:52 -07001603// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001605 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters parameters;
1607 parameters.codecs.push_back(kOpusCodec);
1608 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001610 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
ossu20a4b3f2017-04-27 02:08:52 -07001613// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001615 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
1618 parameters.codecs[0].bitrate = 30000;
1619 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001620 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001621 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001622}
1623
stefan13f1a0a2016-11-30 07:22:58 -08001624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1625 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1626 200000);
1627}
1628
1629TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1630 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1631}
1632
1633TEST_F(WebRtcVoiceEngineTestFake,
1634 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1635 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1636}
1637
1638TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1639 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1640}
1641
Yves Gerey665174f2018-06-19 15:03:05 +02001642TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001643 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1644 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001645 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001646 // Setting max bitrate should keep previous min bitrate
1647 // Setting max bitrate should not reset start bitrate.
1648 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1649 SetSdpBitrateParameters(
1650 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1651 Field(&BitrateConstraints::start_bitrate_bps, -1),
1652 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001653 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001654}
1655
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001656// Test that we can enable NACK with opus as callee.
1657TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001658 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001659 cricket::AudioSendParameters parameters;
1660 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001661 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1662 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001663 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001665 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001667
Yves Gerey665174f2018-06-19 15:03:05 +02001668 EXPECT_TRUE(
1669 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001670}
1671
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672// Test that we can enable NACK on receive streams.
1673TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001674 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 cricket::AudioSendParameters parameters;
1677 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001678 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1679 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001682 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683}
1684
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685// Test that we can disable NACK on receive streams.
1686TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001691 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1692 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001695
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001696 parameters.codecs.clear();
1697 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700}
1701
1702// Test that NACK is enabled on a new receive stream.
1703TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001704 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 cricket::AudioSendParameters parameters;
1706 parameters.codecs.push_back(kIsacCodec);
1707 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001708 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1709 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711
solenberg2100c0b2017-03-01 11:29:29 -08001712 EXPECT_TRUE(AddRecvStream(kSsrcY));
1713 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1714 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1715 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716}
1717
stefanba4c0e42016-02-04 04:12:24 -08001718TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001719 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001720 cricket::AudioSendParameters send_parameters;
1721 send_parameters.codecs.push_back(kOpusCodec);
1722 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001724
1725 cricket::AudioRecvParameters recv_parameters;
1726 recv_parameters.codecs.push_back(kIsacCodec);
1727 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001728 EXPECT_TRUE(AddRecvStream(kSsrcX));
1729 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001730 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001731 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001732
ossudedfd282016-06-14 07:12:39 -07001733 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001735 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001736 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001737 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001738}
1739
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001740// Test that we can switch back and forth between Opus and ISAC with CN.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001743
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters opus_parameters;
1745 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001746 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001747 {
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(111, spec.payload_type);
1750 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001751 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001753 cricket::AudioSendParameters isac_parameters;
1754 isac_parameters.codecs.push_back(kIsacCodec);
1755 isac_parameters.codecs.push_back(kCn16000Codec);
1756 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001758 {
ossu20a4b3f2017-04-27 02:08:52 -07001759 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1760 EXPECT_EQ(103, spec.payload_type);
1761 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001765 {
ossu20a4b3f2017-04-27 02:08:52 -07001766 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1767 EXPECT_EQ(111, spec.payload_type);
1768 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001769 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770}
1771
1772// Test that we handle various ways of specifying bitrate.
1773TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001774 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 cricket::AudioSendParameters parameters;
1776 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001778 {
ossu20a4b3f2017-04-27 02:08:52 -07001779 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1780 EXPECT_EQ(103, spec.payload_type);
1781 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1782 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001783 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784
Yves Gerey665174f2018-06-19 15:03:05 +02001785 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001787 {
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(103, spec.payload_type);
1790 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1791 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001792 }
Yves Gerey665174f2018-06-19 15:03:05 +02001793 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001795 {
ossu20a4b3f2017-04-27 02:08:52 -07001796 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1797 EXPECT_EQ(103, spec.payload_type);
1798 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1799 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001800 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801
Yves Gerey665174f2018-06-19 15:03:05 +02001802 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001804 {
ossu20a4b3f2017-04-27 02:08:52 -07001805 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1806 EXPECT_EQ(0, spec.payload_type);
1807 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1808 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001809 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810
Yves Gerey665174f2018-06-19 15:03:05 +02001811 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001812 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001813 {
ossu20a4b3f2017-04-27 02:08:52 -07001814 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1815 EXPECT_EQ(0, spec.payload_type);
1816 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1817 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001818 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001820 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001821 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001822 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001823 {
ossu20a4b3f2017-04-27 02:08:52 -07001824 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1825 EXPECT_EQ(111, spec.payload_type);
1826 EXPECT_STREQ("opus", spec.format.name.c_str());
1827 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001828 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829}
1830
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001831// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001833 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 cricket::AudioSendParameters parameters;
1835 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001836}
1837
1838// Test that we can set send codecs even with telephone-event codec as the first
1839// one on the list.
1840TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001841 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001842 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001843 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 parameters.codecs.push_back(kIsacCodec);
1845 parameters.codecs.push_back(kPcmuCodec);
1846 parameters.codecs[0].id = 98; // DTMF
1847 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001848 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001849 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1850 EXPECT_EQ(96, spec.payload_type);
1851 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001852 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001853 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001854}
1855
Harald Alvestranda1f66612018-02-21 11:24:23 +01001856// Test that CanInsertDtmf() is governed by the send flag
1857TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1858 EXPECT_TRUE(SetupSendStream());
1859 cricket::AudioSendParameters parameters;
1860 parameters.codecs.push_back(kTelephoneEventCodec1);
1861 parameters.codecs.push_back(kPcmuCodec);
1862 parameters.codecs[0].id = 98; // DTMF
1863 parameters.codecs[1].id = 96;
1864 SetSendParameters(parameters);
1865 EXPECT_FALSE(channel_->CanInsertDtmf());
1866 SetSend(true);
1867 EXPECT_TRUE(channel_->CanInsertDtmf());
1868 SetSend(false);
1869 EXPECT_FALSE(channel_->CanInsertDtmf());
1870}
1871
solenberg31642aa2016-03-14 08:00:37 -07001872// Test that payload type range is limited for telephone-event codec.
1873TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001874 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001875 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001876 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001877 parameters.codecs.push_back(kIsacCodec);
1878 parameters.codecs[0].id = 0; // DTMF
1879 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001881 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001882 EXPECT_TRUE(channel_->CanInsertDtmf());
1883 parameters.codecs[0].id = 128; // DTMF
1884 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1885 EXPECT_FALSE(channel_->CanInsertDtmf());
1886 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001887 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001888 EXPECT_TRUE(channel_->CanInsertDtmf());
1889 parameters.codecs[0].id = -1; // DTMF
1890 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1891 EXPECT_FALSE(channel_->CanInsertDtmf());
1892}
1893
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001894// Test that we can set send codecs even with CN codec as the first
1895// one on the list.
1896TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001897 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001898 cricket::AudioSendParameters parameters;
1899 parameters.codecs.push_back(kCn16000Codec);
1900 parameters.codecs.push_back(kIsacCodec);
1901 parameters.codecs.push_back(kPcmuCodec);
1902 parameters.codecs[0].id = 98; // wideband CN
1903 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001904 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001905 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1906 EXPECT_EQ(96, send_codec_spec.payload_type);
1907 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001908 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001909}
1910
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001911// Test that we set VAD and DTMF types correctly as caller.
1912TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001913 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 cricket::AudioSendParameters parameters;
1915 parameters.codecs.push_back(kIsacCodec);
1916 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 parameters.codecs.push_back(kCn16000Codec);
1919 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001920 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 parameters.codecs[0].id = 96;
1922 parameters.codecs[2].id = 97; // wideband CN
1923 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001924 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001925 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1926 EXPECT_EQ(96, send_codec_spec.payload_type);
1927 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001928 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001929 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001930 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001931 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001932}
1933
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001934// Test that we set VAD and DTMF types correctly as callee.
1935TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001936 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 cricket::AudioSendParameters parameters;
1938 parameters.codecs.push_back(kIsacCodec);
1939 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001940 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 parameters.codecs.push_back(kCn16000Codec);
1942 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001943 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs[0].id = 96;
1945 parameters.codecs[2].id = 97; // wideband CN
1946 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001948 EXPECT_TRUE(
1949 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001950
ossu20a4b3f2017-04-27 02:08:52 -07001951 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1952 EXPECT_EQ(96, send_codec_spec.payload_type);
1953 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001954 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001955 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001956 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001957 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001958}
1959
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960// Test that we only apply VAD if we have a CN codec that matches the
1961// send codec clockrate.
1962TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001963 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001964 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001966 parameters.codecs.push_back(kIsacCodec);
1967 parameters.codecs.push_back(kCn16000Codec);
1968 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001969 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001970 {
ossu20a4b3f2017-04-27 02:08:52 -07001971 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1972 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001973 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001974 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001975 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001979 {
ossu20a4b3f2017-04-27 02:08:52 -07001980 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1981 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001982 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001983 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001984 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001985 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001987 {
ossu20a4b3f2017-04-27 02:08:52 -07001988 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1989 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001990 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001991 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001992 }
Brave Yao5225dd82015-03-26 07:39:19 +08001993 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001994 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001995 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001996 {
ossu20a4b3f2017-04-27 02:08:52 -07001997 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1998 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001999 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002000 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002001}
2002
2003// Test that we perform case-insensitive matching of codec names.
2004TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002005 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002006 cricket::AudioSendParameters parameters;
2007 parameters.codecs.push_back(kIsacCodec);
2008 parameters.codecs.push_back(kPcmuCodec);
2009 parameters.codecs.push_back(kCn16000Codec);
2010 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002011 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 parameters.codecs[0].name = "iSaC";
2013 parameters.codecs[0].id = 96;
2014 parameters.codecs[2].id = 97; // wideband CN
2015 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002017 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2018 EXPECT_EQ(96, send_codec_spec.payload_type);
2019 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002020 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002021 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002022 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002023 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002024}
2025
stefanba4c0e42016-02-04 04:12:24 -08002026class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2027 public:
2028 WebRtcVoiceEngineWithSendSideBweTest()
2029 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2030};
2031
2032TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2033 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002034 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2035 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002036 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002037 "uri", &RtpExtension::uri,
2038 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002039}
2040
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002041// Test support for audio level header extension.
2042TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002043 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002044}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002045TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002046 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002047}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002048
solenbergd4adce42016-11-17 06:26:52 -08002049// Test support for transport sequence number header extension.
2050TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2051 TestSetSendRtpHeaderExtensions(
2052 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002053}
solenbergd4adce42016-11-17 06:26:52 -08002054TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2055 TestSetRecvRtpHeaderExtensions(
2056 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002057}
2058
solenberg1ac56142015-10-13 03:58:19 -07002059// Test that we can create a channel and start sending on it.
2060TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002061 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(send_parameters_);
2063 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002064 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002066 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002067}
2068
2069// Test that a channel will send if and only if it has a source and is enabled
2070// for sending.
2071TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002072 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002073 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002074 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002075 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002076 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2077 SetAudioSend(kSsrcX, true, &fake_source_);
2078 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2079 SetAudioSend(kSsrcX, true, nullptr);
2080 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002081}
2082
solenberg94218532016-06-16 10:53:22 -07002083// Test that a channel is muted/unmuted.
2084TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2085 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002086 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002087 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2088 SetAudioSend(kSsrcX, true, nullptr);
2089 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2090 SetAudioSend(kSsrcX, false, nullptr);
2091 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002092}
2093
solenberg6d6e7c52016-04-13 09:07:30 -07002094// Test that SetSendParameters() does not alter a stream's send state.
2095TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2096 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002098
2099 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002100 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002101 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002102
2103 // Changing RTP header extensions will recreate the AudioSendStream.
2104 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002105 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002106 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002107 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002108
2109 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002110 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002112
2113 // Changing RTP header extensions will recreate the AudioSendStream.
2114 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002115 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002117}
2118
solenberg1ac56142015-10-13 03:58:19 -07002119// Test that we can create a channel and start playing out on it.
2120TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002121 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002122 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002123 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002124 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002125 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002126 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127}
2128
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129// Test that we can add and remove send streams.
2130TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2131 SetupForMultiSendStream();
2132
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002134 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135
solenbergc96df772015-10-21 13:01:53 -07002136 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002137 EXPECT_TRUE(
2138 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002139 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002141 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142 }
tfarina5237aaf2015-11-10 23:44:30 -08002143 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144
solenbergc96df772015-10-21 13:01:53 -07002145 // Delete the send streams.
2146 for (uint32_t ssrc : kSsrcs4) {
2147 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002148 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002149 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150 }
solenbergc96df772015-10-21 13:01:53 -07002151 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152}
2153
2154// Test SetSendCodecs correctly configure the codecs in all send streams.
2155TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2156 SetupForMultiSendStream();
2157
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002159 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002160 EXPECT_TRUE(
2161 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162 }
2163
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002164 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002166 parameters.codecs.push_back(kIsacCodec);
2167 parameters.codecs.push_back(kCn16000Codec);
2168 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002169 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170
2171 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002172 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002173 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2174 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002175 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2176 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002177 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002178 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 }
2180
minyue7a973442016-10-20 03:27:12 -07002181 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002182 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002184 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002185 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2186 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002187 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2188 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002189 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
2191}
2192
2193// Test we can SetSend on all send streams correctly.
2194TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2195 SetupForMultiSendStream();
2196
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002197 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002198 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002199 EXPECT_TRUE(
2200 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002201 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 }
2204
2205 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002206 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002207 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002209 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002210 }
2211
2212 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002213 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002214 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002216 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002217 }
2218}
2219
2220// Test we can set the correct statistics on all send streams.
2221TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2222 SetupForMultiSendStream();
2223
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002225 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002226 EXPECT_TRUE(
2227 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 }
solenberg85a04962015-10-27 03:35:21 -07002229
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002230 // Create a receive stream to check that none of the send streams end up in
2231 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002232 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002233
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002234 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002236 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002237 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002238
solenberg85a04962015-10-27 03:35:21 -07002239 // Check stats for the added streams.
2240 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002241 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002242 cricket::VoiceMediaInfo info;
2243 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002244
solenberg85a04962015-10-27 03:35:21 -07002245 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002246 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002247 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002248 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002249 }
hbos1acfbd22016-11-17 23:43:29 -08002250 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002251
2252 // We have added one receive stream. We should see empty stats.
2253 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002254 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002255 }
solenberg1ac56142015-10-13 03:58:19 -07002256
solenberg2100c0b2017-03-01 11:29:29 -08002257 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002258 {
2259 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002260 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002261 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002262 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002263 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002264 EXPECT_EQ(0u, info.receivers.size());
2265 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002266
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002267 // Deliver a new packet - a default receive stream should be created and we
2268 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002269 {
2270 cricket::VoiceMediaInfo info;
2271 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2272 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002273 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002274 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002275 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002276 EXPECT_EQ(1u, info.receivers.size());
2277 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002278 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002279 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002280}
2281
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282// Test that we can add and remove receive streams, and do proper send/playout.
2283// We can receive on multiple streams while sending one stream.
2284TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002285 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002286
solenberg1ac56142015-10-13 03:58:19 -07002287 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002288 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002289 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290
solenberg1ac56142015-10-13 03:58:19 -07002291 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002293 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
solenberg1ac56142015-10-13 03:58:19 -07002296 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002297 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298
2299 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2301 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2302 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
2304 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002305 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307
2308 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002309 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2311 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312
aleloi84ef6152016-08-04 05:28:21 -07002313 // Restart playout and make sure recv streams are played out.
2314 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002315 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2316 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
aleloi84ef6152016-08-04 05:28:21 -07002318 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2320 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321}
2322
wu@webrtc.org97077a32013-10-25 21:18:33 +00002323TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002324 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002325 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002326 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002327 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002328 const auto& agc_config = apm_config_.gain_controller1;
2329
2330 // Ensure default options.
2331 VerifyGainControlEnabledCorrectly();
2332 VerifyGainControlDefaultSettings();
2333
2334 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002335 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002336 EXPECT_FALSE(agc_config.enabled);
2337 send_parameters_.options.auto_gain_control = absl::nullopt;
2338
2339 send_parameters_.options.tx_agc_target_dbov = 5;
2340 SetSendParameters(send_parameters_);
2341 EXPECT_EQ(5, agc_config.target_level_dbfs);
2342 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2343
2344 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(10, agc_config.compression_gain_db);
2347 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2348
2349 send_parameters_.options.tx_agc_limiter = false;
2350 SetSendParameters(send_parameters_);
2351 EXPECT_FALSE(agc_config.enable_limiter);
2352 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2353
2354 SetSendParameters(send_parameters_);
2355 // Expect all options to have been preserved.
2356 EXPECT_FALSE(agc_config.enabled);
2357 EXPECT_EQ(5, agc_config.target_level_dbfs);
2358 EXPECT_EQ(10, agc_config.compression_gain_db);
2359 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002360}
2361
minyue6b825df2016-10-31 04:08:32 -07002362TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2363 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002364 send_parameters_.options.audio_network_adaptor = true;
2365 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002366 SetSendParameters(send_parameters_);
2367 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002368 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002369}
2370
2371TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2372 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002373 send_parameters_.options.audio_network_adaptor = true;
2374 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002375 SetSendParameters(send_parameters_);
2376 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002377 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002378 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002379 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002380 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002381 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002382}
2383
2384TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2385 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002386 send_parameters_.options.audio_network_adaptor = true;
2387 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002388 SetSendParameters(send_parameters_);
2389 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002391 const int initial_num = call_.GetNumCreatedSendStreams();
2392 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002393 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002394 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2395 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002396 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002397 // AudioSendStream not expected to be recreated.
2398 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2399 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002400 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002401}
2402
michaelt6672b262017-01-11 10:17:59 -08002403class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2404 : public WebRtcVoiceEngineTestFake {
2405 public:
2406 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2407 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002408 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2409 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002410 "Enabled/") {}
2411};
2412
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002414// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002416 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002417 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2421 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002423 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002424 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002425 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002426 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002427 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002428 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429
solenberg85a04962015-10-27 03:35:21 -07002430 // Check stats for the added streams.
2431 {
Alex Narestbbeb1092019-08-16 11:49:04 +02002432 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002433 cricket::VoiceMediaInfo info;
2434 EXPECT_EQ(true, channel_->GetStats(&info));
2435
2436 // We have added one send stream. We should see the stats we've set.
2437 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002438 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002439 // We have added one receive stream. We should see empty stats.
2440 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002441 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002442 }
solenberg1ac56142015-10-13 03:58:19 -07002443
solenberg566ef242015-11-06 15:34:49 -08002444 // Start sending - this affects some reported stats.
2445 {
2446 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002447 SetSend(true);
Alex Narestbbeb1092019-08-16 11:49:04 +02002448 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg566ef242015-11-06 15:34:49 -08002449 EXPECT_EQ(true, channel_->GetStats(&info));
2450 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002451 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002452 }
2453
solenberg2100c0b2017-03-01 11:29:29 -08002454 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002455 {
2456 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002457 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
Alex Narestbbeb1092019-08-16 11:49:04 +02002458 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002459 EXPECT_EQ(true, channel_->GetStats(&info));
2460 EXPECT_EQ(1u, info.senders.size());
2461 EXPECT_EQ(0u, info.receivers.size());
2462 }
solenberg1ac56142015-10-13 03:58:19 -07002463
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002464 // Deliver a new packet - a default receive stream should be created and we
2465 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002466 {
2467 cricket::VoiceMediaInfo info;
2468 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2469 SetAudioReceiveStreamStats();
Alex Narestbbeb1092019-08-16 11:49:04 +02002470 EXPECT_CALL(adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
solenberg85a04962015-10-27 03:35:21 -07002471 EXPECT_EQ(true, channel_->GetStats(&info));
2472 EXPECT_EQ(1u, info.senders.size());
2473 EXPECT_EQ(1u, info.receivers.size());
2474 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002475 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002476 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477}
2478
2479// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002480// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002482 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2484 EXPECT_TRUE(AddRecvStream(kSsrcY));
2485 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486}
2487
2488// Test that the local SSRC is the same on sending and receiving channels if the
2489// receive channel is created before the send channel.
2490TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002491 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002492 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002493 EXPECT_TRUE(
2494 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002495 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2496 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497}
2498
2499// Test that we can properly receive packets.
2500TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002501 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002502 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002504
Yves Gerey665174f2018-06-19 15:03:05 +02002505 EXPECT_TRUE(
2506 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507}
2508
2509// Test that we can properly receive packets on multiple streams.
2510TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002511 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002512 const uint32_t ssrc1 = 1;
2513 const uint32_t ssrc2 = 2;
2514 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002515 EXPECT_TRUE(AddRecvStream(ssrc1));
2516 EXPECT_TRUE(AddRecvStream(ssrc2));
2517 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002518 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002519 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002520 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002521 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002522 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 }
mflodman3d7db262016-04-29 00:57:13 -07002524
2525 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2526 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2527 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2528
2529 EXPECT_EQ(s1.received_packets(), 0);
2530 EXPECT_EQ(s2.received_packets(), 0);
2531 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002532
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002534 EXPECT_EQ(s1.received_packets(), 0);
2535 EXPECT_EQ(s2.received_packets(), 0);
2536 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002537
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(s1.received_packets(), 1);
2540 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
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[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002545 EXPECT_EQ(s1.received_packets(), 1);
2546 EXPECT_EQ(s2.received_packets(), 1);
2547 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
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[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002551 EXPECT_EQ(s1.received_packets(), 1);
2552 EXPECT_EQ(s2.received_packets(), 1);
2553 EXPECT_EQ(s3.received_packets(), 1);
2554 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002555
mflodman3d7db262016-04-29 00:57:13 -07002556 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2557 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2558 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002559}
2560
solenberg2100c0b2017-03-01 11:29:29 -08002561// Test that receiving on an unsignaled stream works (a stream is created).
2562TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002563 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002564 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002565
solenberg7e63ef02015-11-20 00:19:43 -08002566 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002567
Mirko Bonadeif859e552018-05-30 15:31:29 +02002568 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002569 EXPECT_TRUE(
2570 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002571}
2572
Seth Hampson5897a6e2018-04-03 11:16:33 -07002573// Tests that when we add a stream without SSRCs, but contains a stream_id
2574// that it is stored and its stream id is later used when the first packet
2575// arrives to properly create a receive stream with a sync label.
2576TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2577 const char kSyncLabel[] = "sync_label";
2578 EXPECT_TRUE(SetupChannel());
2579 cricket::StreamParams unsignaled_stream;
2580 unsignaled_stream.set_stream_ids({kSyncLabel});
2581 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2582 // The stream shouldn't have been created at this point because it doesn't
2583 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002584 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002585
2586 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2587
Mirko Bonadeif859e552018-05-30 15:31:29 +02002588 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002589 EXPECT_TRUE(
2590 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2591 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2592
Saurav Dasff27da52019-09-20 11:05:30 -07002593 // Remset the unsignaled stream to clear the cached parameters. If a new
Seth Hampson5897a6e2018-04-03 11:16:33 -07002594 // default unsignaled receive stream is created it will not have a sync group.
Saurav Dasff27da52019-09-20 11:05:30 -07002595 channel_->ResetUnsignaledRecvStream();
Seth Hampson5897a6e2018-04-03 11:16:33 -07002596 channel_->RemoveRecvStream(kSsrc1);
2597
2598 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2599
Mirko Bonadeif859e552018-05-30 15:31:29 +02002600 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002601 EXPECT_TRUE(
2602 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2603 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2604}
2605
solenberg2100c0b2017-03-01 11:29:29 -08002606// Test that receiving N unsignaled stream works (streams will be created), and
2607// that packets are forwarded to them all.
2608TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002609 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002610 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002611 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2612
solenberg2100c0b2017-03-01 11:29:29 -08002613 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002614 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002615 rtc::SetBE32(&packet[8], ssrc);
2616 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002617
solenberg2100c0b2017-03-01 11:29:29 -08002618 // Verify we have one new stream for each loop iteration.
2619 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002620 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2621 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002622 }
mflodman3d7db262016-04-29 00:57:13 -07002623
solenberg2100c0b2017-03-01 11:29:29 -08002624 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002625 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002626 rtc::SetBE32(&packet[8], ssrc);
2627 DeliverPacket(packet, sizeof(packet));
2628
solenbergebb349d2017-03-13 05:46:15 -07002629 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002630 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2631 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2632 }
2633
2634 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2635 constexpr uint32_t kAnotherSsrc = 667;
2636 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002637 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002638
2639 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002640 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002641 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002642 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002643 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2644 EXPECT_EQ(2, streams[i]->received_packets());
2645 }
2646 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2647 EXPECT_EQ(1, streams[i]->received_packets());
2648 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002649 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002650}
2651
solenberg2100c0b2017-03-01 11:29:29 -08002652// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002653// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002654TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002655 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002656 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002657 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2658
2659 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002660 const uint32_t signaled_ssrc = 1;
2661 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002662 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002663 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002664 EXPECT_TRUE(
2665 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002666 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002667
2668 // Note that the first unknown SSRC cannot be 0, because we only support
2669 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002670 const uint32_t unsignaled_ssrc = 7011;
2671 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002672 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002673 EXPECT_TRUE(
2674 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002675 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002676
2677 DeliverPacket(packet, sizeof(packet));
2678 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2679
2680 rtc::SetBE32(&packet[8], signaled_ssrc);
2681 DeliverPacket(packet, sizeof(packet));
2682 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002683 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002684}
2685
solenberg4904fb62017-02-17 12:01:14 -08002686// Two tests to verify that adding a receive stream with the same SSRC as a
2687// previously added unsignaled stream will only recreate underlying stream
2688// objects if the stream parameters have changed.
2689TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2690 EXPECT_TRUE(SetupChannel());
2691
2692 // Spawn unsignaled stream with SSRC=1.
2693 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002694 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002695 EXPECT_TRUE(
2696 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002697
2698 // Verify that the underlying stream object in Call is not recreated when a
2699 // stream with SSRC=1 is added.
2700 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002701 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002702 int audio_receive_stream_id = streams.front()->id();
2703 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002704 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002705 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2706}
2707
2708TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2709 EXPECT_TRUE(SetupChannel());
2710
2711 // Spawn unsignaled stream with SSRC=1.
2712 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002713 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002714 EXPECT_TRUE(
2715 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002716
2717 // Verify that the underlying stream object in Call *is* recreated when a
2718 // stream with SSRC=1 is added, and which has changed stream parameters.
2719 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002720 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002721 int audio_receive_stream_id = streams.front()->id();
2722 cricket::StreamParams stream_params;
2723 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002724 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002725 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002726 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002727 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2728}
2729
solenberg1ac56142015-10-13 03:58:19 -07002730// Test that AddRecvStream creates new stream.
2731TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002732 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002733 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734}
2735
2736// Test that after adding a recv stream, we do not decode more codecs than
2737// those previously passed into SetRecvCodecs.
2738TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002739 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002740 cricket::AudioRecvParameters parameters;
2741 parameters.codecs.push_back(kIsacCodec);
2742 parameters.codecs.push_back(kPcmuCodec);
2743 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002744 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002745 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2746 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2747 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748}
2749
2750// Test that we properly clean up any streams that were added, even if
2751// not explicitly removed.
2752TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002753 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002754 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002755 EXPECT_TRUE(AddRecvStream(1));
2756 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002757
Mirko Bonadeif859e552018-05-30 15:31:29 +02002758 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2759 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760 delete channel_;
2761 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002762 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2763 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764}
2765
Saurav Dasff27da52019-09-20 11:05:30 -07002766TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamSuccessWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002767 EXPECT_TRUE(SetupSendStream());
Saurav Dasff27da52019-09-20 11:05:30 -07002768 EXPECT_TRUE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002769}
2770
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002771TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002773 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002774 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002775}
2776
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002777// Test the InsertDtmf on default send stream as caller.
2778TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002779 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002780}
2781
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002782// Test the InsertDtmf on default send stream as callee
2783TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002784 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002785}
2786
2787// Test the InsertDtmf on specified send stream as caller.
2788TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002789 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002790}
2791
2792// Test the InsertDtmf on specified send stream as callee.
2793TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002794 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795}
2796
Johannes Kron9190b822018-10-29 11:22:05 +01002797// Test propagation of extmap allow mixed setting.
2798TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2799 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2800}
2801TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2802 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2803}
2804TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2805 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2806}
2807TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2808 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2809}
2810
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002812 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002813 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002814 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002815 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002816 .WillRepeatedly(Return(false));
2817 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2818 .Times(4)
2819 .WillRepeatedly(Return(false));
2820 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2821 .Times(2)
2822 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002823
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002824 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002825 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002826
solenberg246b8172015-12-08 09:50:23 -08002827 // Nothing set in AudioOptions, so everything should be as default.
2828 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002830 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002831 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002832 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002833 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002834 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002835
Sam Zackrissonba502232019-01-04 10:36:48 +01002836 // Turn typing detection off.
2837 send_parameters_.options.typing_detection = false;
2838 SetSendParameters(send_parameters_);
2839 EXPECT_FALSE(IsTypingDetectionEnabled());
2840
2841 // Leave typing detection unchanged, but non-default.
2842 send_parameters_.options.typing_detection = absl::nullopt;
2843 SetSendParameters(send_parameters_);
2844 EXPECT_FALSE(IsTypingDetectionEnabled());
2845
2846 // Turn typing detection on.
2847 send_parameters_.options.typing_detection = true;
2848 SetSendParameters(send_parameters_);
2849 EXPECT_TRUE(IsTypingDetectionEnabled());
2850
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002851 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002852 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002853 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002854 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002855
2856 // Turn echo cancellation back on, with settings, and make sure
2857 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002858 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002859 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002860 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002861
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002862 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002863 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002864 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002865 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002866
Per Åhgrenf40a3402019-04-25 08:50:11 +02002867 // Restore AEC to be on to work with the following tests.
2868 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002869 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002870
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002871 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002873 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002874 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002875 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002876
2877 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002878 send_parameters_.options.auto_gain_control = true;
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_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002883 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002884 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002886 send_parameters_.options.noise_suppression = false;
2887 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002888 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002889 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002890 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002891 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002892 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893
solenberg1ac56142015-10-13 03:58:19 -07002894 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002895 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002896 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002897 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002898 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002899 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900}
2901
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002903 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002904 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2905 .Times(8)
2906 .WillRepeatedly(Return(false));
2907 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2908 .Times(8)
2909 .WillRepeatedly(Return(false));
2910 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2911 .Times(8)
2912 .WillRepeatedly(Return(false));
2913 EXPECT_CALL(adm_, RecordingIsInitialized())
2914 .Times(2)
2915 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002916 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2917 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002918 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002919
kwiberg686a8ef2016-02-26 03:00:35 -08002920 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002921 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2922 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2923 cricket::AudioOptions(),
2924 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002925 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002926 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2927 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2928 cricket::AudioOptions(),
2929 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930
2931 // Have to add a stream to make SetSend work.
2932 cricket::StreamParams stream1;
2933 stream1.ssrcs.push_back(1);
2934 channel1->AddSendStream(stream1);
2935 cricket::StreamParams stream2;
2936 stream2.ssrcs.push_back(2);
2937 channel2->AddSendStream(stream2);
2938
2939 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002940 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002941 parameters_options_all.options.echo_cancellation = true;
2942 parameters_options_all.options.auto_gain_control = true;
2943 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002944 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002945 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002946 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002947 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002948 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002949 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002950 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002951 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002952 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002953 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002954
2955 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002956 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002957 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002958 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002959 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002960 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002961 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002962 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002963 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002964 expected_options.echo_cancellation = true;
2965 expected_options.auto_gain_control = true;
2966 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002967 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968
2969 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002970 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002971 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002972 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002973 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002974 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002975 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002976 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002977 expected_options.echo_cancellation = true;
2978 expected_options.auto_gain_control = false;
2979 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002980 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002982 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002983 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002984 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002985 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002986 VerifyGainControlEnabledCorrectly();
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(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002990 channel1->SetSend(true);
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(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002996 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002997 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002998 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3002 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003003 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3004 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003005 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003006 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003007 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003008 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003009 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003010 expected_options.echo_cancellation = true;
3011 expected_options.auto_gain_control = false;
3012 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003013 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014}
3015
wu@webrtc.orgde305012013-10-31 15:40:38 +00003016// This test verifies DSCP settings are properly applied on voice media channel.
3017TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003018 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003019 cricket::FakeNetworkInterface network_interface;
3020 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003021 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003022 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003023
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003024 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003025
Sebastian Jansson84848f22018-11-16 10:40:36 +01003026 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3027 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3028 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003029 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003030 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3031 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3032
3033 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003034 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3035 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3036 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003037 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003038 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3039
3040 // Create a send stream to configure
3041 EXPECT_TRUE(
3042 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3043 parameters = channel->GetRtpSendParameters(kSsrcZ);
3044 ASSERT_FALSE(parameters.encodings.empty());
3045
3046 // Various priorities map to various dscp values.
3047 parameters.encodings[0].network_priority = 4.0;
3048 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003049 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003050 parameters.encodings[0].network_priority = 0.5;
3051 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3052 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3053
3054 // A bad priority does not change the dscp value.
3055 parameters.encodings[0].network_priority = 0.0;
3056 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3057 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003058
Tim Haloun6ca98362018-09-17 17:06:08 -07003059 // Packets should also self-identify their dscp in PacketOptions.
3060 const uint8_t kData[10] = {0};
3061 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003062 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003063
nisse51542be2016-02-12 02:27:06 -08003064 // Verify that setting the option to false resets the
3065 // DiffServCodePoint.
3066 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003067 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3068 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3069 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003070 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003071 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3072 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3073
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003074 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003075}
3076
solenberg4bac9c52015-10-09 02:32:53 -07003077TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003078 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003079 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003080 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003081 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003083 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3084 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3085 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003086}
3087
solenberg2100c0b2017-03-01 11:29:29 -08003088TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003089 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003090
3091 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003092 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003093 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3094
3095 // Should remember the volume "2" which will be set on new unsignaled streams,
3096 // and also set the gain to 2 on existing unsignaled streams.
3097 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3098 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3099
3100 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3101 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3102 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3103 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3104 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3105 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3106
3107 // Setting gain with SSRC=0 should affect all unsignaled streams.
3108 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003109 if (kMaxUnsignaledRecvStreams > 1) {
3110 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3111 }
solenberg2100c0b2017-03-01 11:29:29 -08003112 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3113
3114 // Setting gain on an individual stream affects only that.
3115 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003116 if (kMaxUnsignaledRecvStreams > 1) {
3117 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3118 }
solenberg2100c0b2017-03-01 11:29:29 -08003119 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003120}
3121
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003122TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3123 EXPECT_TRUE(SetupChannel());
3124 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3125 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3126
3127 cricket::StreamParams stream;
3128 stream.ssrcs.push_back(kSsrcY);
3129 EXPECT_TRUE(channel_->AddRecvStream(stream));
3130 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3131 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3132 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3133}
3134
3135TEST_F(WebRtcVoiceEngineTestFake,
3136 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3137 // Here base minimum delay is abbreviated to delay in comments for shortness.
3138 EXPECT_TRUE(SetupChannel());
3139
3140 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3141 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3142 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3143 // Check that it doesn't provide default values for unknown ssrc.
3144 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3145
3146 // Check that default value for unsignaled streams is 0.
3147 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3148
3149 // Should remember the delay 100 which will be set on new unsignaled streams,
3150 // and also set the delay to 100 on existing unsignaled streams.
3151 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3152 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3153 // Check that it doesn't provide default values for unknown ssrc.
3154 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3155
3156 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3157 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3158 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3159 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3160 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3161 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3162
3163 // Setting delay with SSRC=0 should affect all unsignaled streams.
3164 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3165 if (kMaxUnsignaledRecvStreams > 1) {
3166 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3167 }
3168 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3169
3170 // Setting delay on an individual stream affects only that.
3171 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3172 if (kMaxUnsignaledRecvStreams > 1) {
3173 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3174 }
3175 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3176 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3177 // Check that it doesn't provide default values for unknown ssrc.
3178 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3179}
3180
Seth Hampson845e8782018-03-02 11:34:10 -08003181TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003182 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003183 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003184
solenbergff976312016-03-30 23:28:51 -07003185 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003186 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003187 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003188 // Creating two channels to make sure that sync label is set properly for both
3189 // the default voice channel and following ones.
3190 EXPECT_TRUE(channel_->AddRecvStream(sp));
3191 sp.ssrcs[0] += 1;
3192 EXPECT_TRUE(channel_->AddRecvStream(sp));
3193
Mirko Bonadeif859e552018-05-30 15:31:29 +02003194 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003195 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003196 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003197 << "SyncGroup should be set based on stream id";
3198 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003199 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003200 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003201}
3202
solenberg3a941542015-11-16 07:34:50 -08003203// TODO(solenberg): Remove, once recv streams are configured through Call.
3204// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003205TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003206 // Test that setting the header extensions results in the expected state
3207 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003208 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003209 ssrcs.push_back(223);
3210 ssrcs.push_back(224);
3211
solenbergff976312016-03-30 23:28:51 -07003212 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003213 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003214 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003215 EXPECT_TRUE(
3216 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003217 }
3218
Mirko Bonadeif859e552018-05-30 15:31:29 +02003219 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003220 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003221 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003223 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003224 }
3225
3226 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003227 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003228 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003229 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003230 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003231 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003232 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003233 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003234 EXPECT_NE(nullptr, s);
3235 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003236 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3237 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003238 for (const auto& s_ext : s_exts) {
3239 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003240 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003241 }
3242 }
3243 }
3244 }
3245
3246 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003247 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003248 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003249 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003250 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003251 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003252 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003253}
3254
3255TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3256 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003257 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003258 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003259 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003260 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3261 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003263 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003264
solenbergff976312016-03-30 23:28:51 -07003265 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003266 cricket::WebRtcVoiceMediaChannel* media_channel =
3267 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003268 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269 EXPECT_TRUE(media_channel->AddRecvStream(
3270 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3271
Mirko Bonadeif859e552018-05-30 15:31:29 +02003272 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003274 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003276 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003277 EXPECT_EQ(1, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003278}
Minyue2013aec2015-05-13 14:14:42 +02003279
solenberg0a617e22015-10-20 15:49:38 -07003280// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003281// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003282TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003283 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003284 EXPECT_TRUE(AddRecvStream(kSsrcY));
3285 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003286 EXPECT_TRUE(
3287 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003288 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3289 EXPECT_TRUE(AddRecvStream(kSsrcW));
3290 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003291}
3292
solenberg7602aab2016-11-14 11:30:07 -08003293TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3294 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003295 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003296 EXPECT_TRUE(
3297 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003298 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3299 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3300 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003301 EXPECT_TRUE(
3302 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003303 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3304 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003305}
stefan658910c2015-09-03 05:48:32 -07003306
deadbeef884f5852016-01-15 09:20:04 -08003307TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003308 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003309 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3310 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003311
3312 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003313 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3314 EXPECT_TRUE(AddRecvStream(kSsrcX));
3315 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003316
3317 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003318 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3319 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003320
3321 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003322 channel_->SetRawAudioSink(kSsrcX, nullptr);
3323 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003324}
3325
solenberg2100c0b2017-03-01 11:29:29 -08003326TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003327 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003328 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3329 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003330 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3331 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003332
3333 // Should be able to set a default sink even when no stream exists.
3334 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3335
solenberg2100c0b2017-03-01 11:29:29 -08003336 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3337 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003338 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003339 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003340
3341 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003342 channel_->SetRawAudioSink(kSsrc0, nullptr);
3343 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003344
3345 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003346 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3347 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003348
3349 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003350 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003351 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003352 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3353
3354 // Spawn another unsignaled stream - it should be assigned the default sink
3355 // and the previous unsignaled stream should lose it.
3356 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3357 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3358 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3359 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003360 if (kMaxUnsignaledRecvStreams > 1) {
3361 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3362 }
solenberg2100c0b2017-03-01 11:29:29 -08003363 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3364
3365 // Reset the default sink - the second unsignaled stream should lose it.
3366 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003367 if (kMaxUnsignaledRecvStreams > 1) {
3368 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3369 }
solenberg2100c0b2017-03-01 11:29:29 -08003370 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3371
3372 // Try setting the default sink while two streams exists.
3373 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003374 if (kMaxUnsignaledRecvStreams > 1) {
3375 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3376 }
solenberg2100c0b2017-03-01 11:29:29 -08003377 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3378
3379 // Try setting the sink for the first unsignaled stream using its known SSRC.
3380 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003381 if (kMaxUnsignaledRecvStreams > 1) {
3382 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3383 }
solenberg2100c0b2017-03-01 11:29:29 -08003384 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003385 if (kMaxUnsignaledRecvStreams > 1) {
3386 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3387 }
deadbeef884f5852016-01-15 09:20:04 -08003388}
3389
skvlad7a43d252016-03-22 15:32:27 -07003390// Test that, just like the video channel, the voice channel communicates the
3391// network state to the call.
3392TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003393 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003394
3395 EXPECT_EQ(webrtc::kNetworkUp,
3396 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3397 EXPECT_EQ(webrtc::kNetworkUp,
3398 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3399
3400 channel_->OnReadyToSend(false);
3401 EXPECT_EQ(webrtc::kNetworkDown,
3402 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3403 EXPECT_EQ(webrtc::kNetworkUp,
3404 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3405
3406 channel_->OnReadyToSend(true);
3407 EXPECT_EQ(webrtc::kNetworkUp,
3408 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3409 EXPECT_EQ(webrtc::kNetworkUp,
3410 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3411}
3412
aleloi18e0b672016-10-04 02:45:47 -07003413// Test that playout is still started after changing parameters
3414TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3415 SetupRecvStream();
3416 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003417 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003418
3419 // Changing RTP header extensions will recreate the AudioReceiveStream.
3420 cricket::AudioRecvParameters parameters;
3421 parameters.extensions.push_back(
3422 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3423 channel_->SetRecvParameters(parameters);
3424
solenberg2100c0b2017-03-01 11:29:29 -08003425 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003426}
3427
Zhi Huangfa266ef2017-12-13 10:27:46 -08003428// Tests when GetSources is called with non-existing ssrc, it will return an
3429// empty list of RtpSource without crashing.
3430TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3431 // Setup an recv stream with |kSsrcX|.
3432 SetupRecvStream();
3433 cricket::WebRtcVoiceMediaChannel* media_channel =
3434 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3435 // Call GetSources with |kSsrcY| which doesn't exist.
3436 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3437 EXPECT_EQ(0u, sources.size());
3438}
3439
stefan658910c2015-09-03 05:48:32 -07003440// Tests that the library initializes and shuts down properly.
3441TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003442 // If the VoiceEngine wants to gather available codecs early, that's fine but
3443 // we never want it to create a decoder at this stage.
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003444 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3445 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003446 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003447 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003448 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003449 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003450 task_queue_factory.get(), &adm,
3451 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003452 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003453 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003454 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003455 webrtc::Call::Config call_config(&event_log);
3456 call_config.task_queue_factory = task_queue_factory.get();
3457 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003458 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3459 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3460 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003461 EXPECT_TRUE(channel != nullptr);
3462 delete channel;
solenbergff976312016-03-30 23:28:51 -07003463}
stefan658910c2015-09-03 05:48:32 -07003464
solenbergff976312016-03-30 23:28:51 -07003465// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003466TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003467 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3468 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003469 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003470 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003471 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003472 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003473 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003474 {
peaha9cc40b2017-06-29 08:32:09 -07003475 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003476 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003477 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003478 task_queue_factory.get(), &adm,
3479 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003480 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003481 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003482 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003483 webrtc::Call::Config call_config(&event_log);
3484 call_config.task_queue_factory = task_queue_factory.get();
3485 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003486 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3487 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3488 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003489 EXPECT_TRUE(channel != nullptr);
3490 delete channel;
3491 }
stefan658910c2015-09-03 05:48:32 -07003492}
3493
ossu20a4b3f2017-04-27 02:08:52 -07003494// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3495TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003496 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3497 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003498 // TODO(ossu): Why are the payload types of codecs with non-static payload
3499 // type assignments checked here? It shouldn't really matter.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003500 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003501 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003502 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003503 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003504 task_queue_factory.get(), &adm,
3505 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003506 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003507 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003508 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003509 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003510 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003511 (clockrate == 0 || codec.clockrate == clockrate);
3512 };
3513 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003514 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003515 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003516 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003517 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003518 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003519 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003520 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003521 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003522 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003523 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003524 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003525 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3526 // Remove these checks once both send and receive side assigns payload
3527 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003528 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003529 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003530 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003531 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003532 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003533 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003534 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003535 EXPECT_EQ(111, codec.id);
3536 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3537 EXPECT_EQ("10", codec.params.find("minptime")->second);
3538 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3539 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003540 }
3541 }
stefan658910c2015-09-03 05:48:32 -07003542}
3543
3544// Tests that VoE supports at least 32 channels
3545TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003546 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3547 webrtc::CreateDefaultTaskQueueFactory();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003548 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003549 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003550 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003551 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003552 task_queue_factory.get(), &adm,
3553 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003554 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003555 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003556 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003557 webrtc::Call::Config call_config(&event_log);
3558 call_config.task_queue_factory = task_queue_factory.get();
3559 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
stefan658910c2015-09-03 05:48:32 -07003560
3561 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003562 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003563 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003564 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3565 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3566 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003567 if (!channel)
3568 break;
stefan658910c2015-09-03 05:48:32 -07003569 channels[num_channels++] = channel;
3570 }
3571
Mirko Bonadeif859e552018-05-30 15:31:29 +02003572 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003573 EXPECT_EQ(expected, num_channels);
3574
3575 while (num_channels > 0) {
3576 delete channels[--num_channels];
3577 }
stefan658910c2015-09-03 05:48:32 -07003578}
3579
3580// Test that we set our preferred codecs properly.
3581TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003582 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3583 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003584 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3585 // - Check that our builtin codecs are usable by Channel.
3586 // - The codecs provided by the engine is usable by Channel.
3587 // It does not check that the codecs in the RecvParameters are actually
3588 // what we sent in - though it's probably reasonable to expect so, if
3589 // SetRecvParameters returns true.
3590 // I think it will become clear once audio decoder injection is completed.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003591 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003592 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003593 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003594 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003595 task_queue_factory.get(), &adm,
3596 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003597 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003598 engine.Init();
Danil Chapovalov83bbe912019-08-07 12:24:53 +02003599 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02003600 webrtc::Call::Config call_config(&event_log);
3601 call_config.task_queue_factory = task_queue_factory.get();
3602 auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
nisse51542be2016-02-12 02:27:06 -08003603 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003604 cricket::AudioOptions(),
3605 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003606 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003607 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003608 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003609}
ossu9def8002017-02-09 05:14:32 -08003610
3611TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3612 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003613 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3614 {48000, 2, 16000, 10000, 20000}};
3615 spec1.info.allow_comfort_noise = false;
3616 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003617 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003618 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3619 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003620 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003621 specs.push_back(webrtc::AudioCodecSpec{
3622 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3623 {16000, 1, 13300}});
3624 specs.push_back(
3625 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3626 specs.push_back(
3627 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003628
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003629 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3630 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003631 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3632 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3633 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003634 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003635 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003636 .WillOnce(Return(specs));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003637 ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003638
peaha9cc40b2017-06-29 08:32:09 -07003639 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003640 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalov4c7112a2019-03-27 18:51:45 +01003641 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3642 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003643 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003644 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003645 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003646 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003647
3648 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3649 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003650 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3651 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3652 if (codecs.size() > index)
3653 return codecs[index];
3654 return missing_codec;
3655 };
ossu9def8002017-02-09 05:14:32 -08003656
3657 // Ensure the general codecs are generated first and in order.
3658 for (size_t i = 0; i != specs.size(); ++i) {
3659 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3660 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3661 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3662 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3663 }
3664
3665 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003666 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003667 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3668 for (size_t i = 0; i != codecs.size(); ++i) {
3669 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003670 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003671 codec.clockrate == format.clockrate_hz &&
3672 codec.channels == format.num_channels) {
3673 return rtc::checked_cast<int>(i);
3674 }
3675 }
3676 return -1;
3677 };
ossu9def8002017-02-09 05:14:32 -08003678
3679 // Ensure all supplementary codecs are generated last. Their internal ordering
3680 // is not important.
3681 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3682 const int num_specs = static_cast<int>(specs.size());
3683 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3684 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3685 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3686 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3687 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3688 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3689 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3690}