blob: 91fcfeb54944b15e8806af19bd858e1855ddd015 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/webrtc_voice_engine.h"
12
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080015
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020016#include "absl/memory/memory.h"
Niels Möller2edab4c2018-10-22 09:48:08 +020017#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/audio_codecs/builtin_audio_decoder_factory.h"
19#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070020#include "api/media_transport_config.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020021#include "api/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010023#include "api/scoped_refptr.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010024#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "call/call.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/fake_media_engine.h"
27#include "media/base/fake_network_interface.h"
28#include "media/base/fake_rtp.h"
29#include "media/base/media_constants.h"
30#include "media/engine/fake_webrtc_call.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/audio_device/include/mock_audio_device.h"
32#include "modules/audio_processing/include/mock_audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080034#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010035#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "test/field_trial.h"
37#include "test/gtest.h"
38#include "test/mock_audio_decoder_factory.h"
39#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
Elad Alon157540a2019-02-08 23:37:52 +010041using ::testing::_;
42using ::testing::ContainerEq;
43using ::testing::Contains;
44using ::testing::Field;
45using ::testing::Return;
46using ::testing::ReturnPointee;
47using ::testing::SaveArg;
48using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000049
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010051using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020052
solenberg418b7d32017-06-13 00:38:27 -070053constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070054
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
56const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070057const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
59const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070060const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
61const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020062const cricket::AudioCodec kTelephoneEventCodec1(106,
63 "telephone-event",
64 8000,
65 0,
66 1);
67const cricket::AudioCodec kTelephoneEventCodec2(107,
68 "telephone-event",
69 32000,
70 0,
71 1);
solenberg2779bab2016-11-17 04:45:19 -080072
solenberg2100c0b2017-03-01 11:29:29 -080073const uint32_t kSsrc0 = 0;
74const uint32_t kSsrc1 = 1;
75const uint32_t kSsrcX = 0x99;
76const uint32_t kSsrcY = 0x17;
77const uint32_t kSsrcZ = 0x42;
78const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020079const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080
solenberg971cab02016-06-14 10:02:41 -070081constexpr int kRtpHistoryMs = 5000;
82
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010083constexpr webrtc::AudioProcessing::Config::GainController1::Mode
84 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010085#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010086 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010087#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010088 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010089#endif
90
91constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
92 webrtc::NoiseSuppression::kHigh;
93
solenberg9a5f032222017-03-15 06:14:12 -070094void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
95 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010096
97 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010098 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010099 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100100 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700101#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200102 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200103 *adm,
104 SetPlayoutDevice(
105 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
106 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200107 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700108#else
109 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
110#endif // #if defined(WEBRTC_WIN)
111 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200112 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700113 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200115 EXPECT_CALL(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200116 *adm,
117 SetRecordingDevice(
118 ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
119 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
Yves Gerey665174f2018-06-19 15:03:05 +0200120 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100121#else
122 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
123#endif // #if defined(WEBRTC_WIN)
124 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200125 EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
126 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100127 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700128 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
129 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
130 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100131
132 // Teardown.
133 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
134 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
135 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
136 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200137 EXPECT_CALL(*adm, Release())
138 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100139 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700140}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200141} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142
solenbergff976312016-03-30 23:28:51 -0700143// Tests that our stub library "works".
144TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100145 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
146 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700147 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700148 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700149 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
150 new rtc::RefCountedObject<
151 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700152 webrtc::AudioProcessing::Config apm_config;
153 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
154 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200155 EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700156 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700157 {
ossuc54071d2016-08-17 02:45:41 -0700158 cricket::WebRtcVoiceEngine engine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100159 task_queue_factory.get(), &adm,
160 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100161 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700162 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700163 }
solenbergff976312016-03-30 23:28:51 -0700164}
165
deadbeef884f5852016-01-15 09:20:04 -0800166class FakeAudioSink : public webrtc::AudioSinkInterface {
167 public:
168 void OnData(const Data& audio) override {}
169};
170
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800171class FakeAudioSource : public cricket::AudioSource {
172 void SetSink(Sink* sink) override {}
173};
174
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200175class WebRtcVoiceEngineTestFake : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 public:
stefanba4c0e42016-02-04 04:12:24 -0800177 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
178
179 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100180 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
181 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700182 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700183 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100184 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700185 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800186 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700187 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800188 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700189 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
190 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200191 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700192 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800193 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100194 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800195 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700196 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800197 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700198 // factories. Those tests should probably be moved elsewhere.
199 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
200 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100201 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100202 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
203 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700204 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200205 send_parameters_.codecs.push_back(kPcmuCodec);
206 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100207
solenberg76377c52017-02-21 00:54:31 -0800208 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200209 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800210 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100211 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100212 VerifyGainControlEnabledCorrectly();
213 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
solenberg8189b022016-06-14 12:13:00 -0700215
solenbergff976312016-03-30 23:28:51 -0700216 bool SetupChannel() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200217 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100218 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
219 cricket::AudioOptions(),
220 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200221 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000222 }
solenberg8189b022016-06-14 12:13:00 -0700223
solenbergff976312016-03-30 23:28:51 -0700224 bool SetupRecvStream() {
225 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700226 return false;
227 }
solenberg2100c0b2017-03-01 11:29:29 -0800228 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700229 }
solenberg8189b022016-06-14 12:13:00 -0700230
solenbergff976312016-03-30 23:28:51 -0700231 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200232 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
233 }
234
235 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700236 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000237 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 }
Florent Castellidacec712018-05-24 16:24:21 +0200239 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800240 return false;
241 }
peaha9cc40b2017-06-29 08:32:09 -0700242 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800243 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 }
solenberg8189b022016-06-14 12:13:00 -0700245
246 bool AddRecvStream(uint32_t ssrc) {
247 EXPECT_TRUE(channel_);
248 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
249 }
250
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700252 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700253 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800254 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
255 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700256 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800257 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258 }
solenberg8189b022016-06-14 12:13:00 -0700259
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700261 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700262 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 }
solenberg8189b022016-06-14 12:13:00 -0700264
Yves Gerey665174f2018-06-19 15:03:05 +0200265 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100267 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
268 const auto* send_stream = call_.GetAudioSendStream(ssrc);
269 EXPECT_TRUE(send_stream);
270 return *send_stream;
271 }
272
deadbeef884f5852016-01-15 09:20:04 -0800273 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
274 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
275 EXPECT_TRUE(recv_stream);
276 return *recv_stream;
277 }
278
solenberg3a941542015-11-16 07:34:50 -0800279 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800280 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800281 }
282
solenberg7add0582015-11-20 09:59:34 -0800283 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800284 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800285 }
286
solenberg059fb442016-10-26 05:12:24 -0700287 void SetSend(bool enable) {
288 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700289 if (enable) {
290 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
291 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
292 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200293 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700294 }
solenberg059fb442016-10-26 05:12:24 -0700295 channel_->SetSend(enable);
296 }
297
298 void SetSendParameters(const cricket::AudioSendParameters& params) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200299 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
solenberg059fb442016-10-26 05:12:24 -0700300 ASSERT_TRUE(channel_);
301 EXPECT_TRUE(channel_->SetSendParameters(params));
302 }
303
Yves Gerey665174f2018-06-19 15:03:05 +0200304 void SetAudioSend(uint32_t ssrc,
305 bool enable,
306 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700307 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700308 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700309 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700310 if (enable && options) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200311 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
minyue6b825df2016-10-31 04:08:32 -0700312 }
313 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700314 }
315
Yves Gerey665174f2018-06-19 15:03:05 +0200316 void TestInsertDtmf(uint32_t ssrc,
317 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800318 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700319 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700321 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200323 EXPECT_TRUE(
324 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000325 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
329 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800332 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700333 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000335
336 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700337 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200339 EXPECT_TRUE(
340 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000341 }
342
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800344 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100346 // Test send.
347 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800348 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800350 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800351 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800352 EXPECT_EQ(codec.id, telephone_event.payload_type);
353 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100354 EXPECT_EQ(2, telephone_event.event_code);
355 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 }
357
Johannes Kron9190b822018-10-29 11:22:05 +0100358 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
359 // For a caller, the answer will be applied in set remote description
360 // where SetSendParameters() is called.
361 EXPECT_TRUE(SetupChannel());
362 EXPECT_TRUE(
363 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
364 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
365 SetSendParameters(send_parameters_);
366 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
367 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
368 }
369
370 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
371 // For a callee, the answer will be applied in set local description
372 // where SetExtmapAllowMixed() and AddSendStream() are called.
373 EXPECT_TRUE(SetupChannel());
374 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
375 EXPECT_TRUE(
376 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
377
378 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
379 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
380 }
381
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 // Test that send bandwidth is set correctly.
383 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000384 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
385 // |expected_result| is the expected result from SetMaxSendBandwidth().
386 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700387 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
388 int max_bitrate,
389 bool expected_result,
390 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200391 cricket::AudioSendParameters parameters;
392 parameters.codecs.push_back(codec);
393 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700394 if (expected_result) {
395 SetSendParameters(parameters);
396 } else {
397 EXPECT_FALSE(channel_->SetSendParameters(parameters));
398 }
solenberg2100c0b2017-03-01 11:29:29 -0800399 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400 }
401
skvlade0d46372016-04-07 22:59:22 -0700402 // Sets the per-stream maximum bitrate limit for the specified SSRC.
403 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700404 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700405 EXPECT_EQ(1UL, parameters.encodings.size());
406
Oskar Sundbom78807582017-11-16 11:09:55 +0100407 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800408 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700409 }
410
solenberg059fb442016-10-26 05:12:24 -0700411 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700412 cricket::AudioSendParameters send_parameters;
413 send_parameters.codecs.push_back(codec);
414 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700415 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700416 }
417
ossu20a4b3f2017-04-27 02:08:52 -0700418 void CheckSendCodecBitrate(int32_t ssrc,
419 const char expected_name[],
420 int expected_bitrate) {
421 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
422 EXPECT_EQ(expected_name, spec->format.name);
423 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700424 }
425
Danil Chapovalov00c71832018-06-15 15:58:38 +0200426 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700427 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700428 }
429
Danil Chapovalov00c71832018-06-15 15:58:38 +0200430 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
431 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700432 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
433 }
434
skvlade0d46372016-04-07 22:59:22 -0700435 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
436 int global_max,
437 int stream_max,
438 bool expected_result,
439 int expected_codec_bitrate) {
440 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800441 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700442
443 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700444 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800445 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700446
447 // Verify that reading back the parameters gives results
448 // consistent with the Set() result.
449 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800450 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700451 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
452 EXPECT_EQ(expected_result ? stream_max : -1,
453 resulting_parameters.encodings[0].max_bitrate_bps);
454
455 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700457 }
458
stefan13f1a0a2016-11-30 07:22:58 -0800459 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
460 int expected_min_bitrate_bps,
461 const char* start_bitrate_kbps,
462 int expected_start_bitrate_bps,
463 const char* max_bitrate_kbps,
464 int expected_max_bitrate_bps) {
465 EXPECT_TRUE(SetupSendStream());
466 auto& codecs = send_parameters_.codecs;
467 codecs.clear();
468 codecs.push_back(kOpusCodec);
469 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
470 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
471 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100472 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
473 SetSdpBitrateParameters(
474 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
475 expected_min_bitrate_bps),
476 Field(&BitrateConstraints::start_bitrate_bps,
477 expected_start_bitrate_bps),
478 Field(&BitrateConstraints::max_bitrate_bps,
479 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800480
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100481 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800482 }
483
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000484 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700485 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000486
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800488 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000489
490 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700491 send_parameters_.extensions.push_back(
492 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000495
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200497 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700498 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extension is set properly.
502 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700503 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700504 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800505 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
506 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
507 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000508
solenberg7add0582015-11-20 09:59:34 -0800509 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200510 EXPECT_TRUE(
511 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800512 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
513 call_.GetAudioSendStream(kSsrcY));
514 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
515 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
516 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000517
518 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200519 send_parameters_.codecs.push_back(kPcmuCodec);
520 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700521 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800522 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
523 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524 }
525
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000526 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700527 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000528
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000529 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800530 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000531
532 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700533 recv_parameters_.extensions.push_back(
534 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800535 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800536 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000537
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000538 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800539 recv_parameters_.extensions.clear();
540 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800541 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000542
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000543 // Ensure extension is set properly.
544 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700545 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800546 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800547 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
548 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
549 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000550
solenberg7add0582015-11-20 09:59:34 -0800551 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800552 EXPECT_TRUE(AddRecvStream(kSsrcY));
553 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
554 call_.GetAudioReceiveStream(kSsrcY));
555 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
556 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
557 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000558
559 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800560 recv_parameters_.extensions.clear();
561 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800562 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
563 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000564 }
565
solenberg85a04962015-10-27 03:35:21 -0700566 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
567 webrtc::AudioSendStream::Stats stats;
568 stats.local_ssrc = 12;
569 stats.bytes_sent = 345;
570 stats.packets_sent = 678;
571 stats.packets_lost = 9012;
572 stats.fraction_lost = 34.56f;
573 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100574 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700575 stats.ext_seqnum = 789;
576 stats.jitter_ms = 12;
577 stats.rtt_ms = 345;
578 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100579 stats.apm_statistics.delay_median_ms = 234;
580 stats.apm_statistics.delay_standard_deviation_ms = 567;
581 stats.apm_statistics.echo_return_loss = 890;
582 stats.apm_statistics.echo_return_loss_enhancement = 1234;
583 stats.apm_statistics.residual_echo_likelihood = 0.432f;
584 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100585 stats.ana_statistics.bitrate_action_counter = 321;
586 stats.ana_statistics.channel_action_counter = 432;
587 stats.ana_statistics.dtx_action_counter = 543;
588 stats.ana_statistics.fec_action_counter = 654;
589 stats.ana_statistics.frame_length_increase_counter = 765;
590 stats.ana_statistics.frame_length_decrease_counter = 876;
591 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700592 stats.typing_noise_detected = true;
593 return stats;
594 }
595 void SetAudioSendStreamStats() {
596 for (auto* s : call_.GetAudioSendStreams()) {
597 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200598 }
solenberg85a04962015-10-27 03:35:21 -0700599 }
solenberg566ef242015-11-06 15:34:49 -0800600 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
601 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700602 const auto stats = GetAudioSendStreamStats();
603 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
604 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
605 EXPECT_EQ(info.packets_sent, stats.packets_sent);
606 EXPECT_EQ(info.packets_lost, stats.packets_lost);
607 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
608 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800609 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700610 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
611 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
612 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
613 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100614 EXPECT_EQ(info.apm_statistics.delay_median_ms,
615 stats.apm_statistics.delay_median_ms);
616 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
617 stats.apm_statistics.delay_standard_deviation_ms);
618 EXPECT_EQ(info.apm_statistics.echo_return_loss,
619 stats.apm_statistics.echo_return_loss);
620 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
621 stats.apm_statistics.echo_return_loss_enhancement);
622 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
623 stats.apm_statistics.residual_echo_likelihood);
624 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
625 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700626 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
627 stats.ana_statistics.bitrate_action_counter);
628 EXPECT_EQ(info.ana_statistics.channel_action_counter,
629 stats.ana_statistics.channel_action_counter);
630 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
631 stats.ana_statistics.dtx_action_counter);
632 EXPECT_EQ(info.ana_statistics.fec_action_counter,
633 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700634 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
635 stats.ana_statistics.frame_length_increase_counter);
636 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
637 stats.ana_statistics.frame_length_decrease_counter);
638 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
639 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800640 EXPECT_EQ(info.typing_noise_detected,
641 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700642 }
643
644 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
645 webrtc::AudioReceiveStream::Stats stats;
646 stats.remote_ssrc = 123;
647 stats.bytes_rcvd = 456;
648 stats.packets_rcvd = 768;
649 stats.packets_lost = 101;
solenberg85a04962015-10-27 03:35:21 -0700650 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100651 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700652 stats.ext_seqnum = 678;
653 stats.jitter_ms = 901;
654 stats.jitter_buffer_ms = 234;
655 stats.jitter_buffer_preferred_ms = 567;
656 stats.delay_estimate_ms = 890;
657 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700658 stats.total_samples_received = 5678901;
659 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200660 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200661 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100662 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.expand_rate = 5.67f;
664 stats.speech_expand_rate = 8.90f;
665 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200666 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700667 stats.accelerate_rate = 4.56f;
668 stats.preemptive_expand_rate = 7.89f;
669 stats.decoding_calls_to_silence_generator = 12;
670 stats.decoding_calls_to_neteq = 345;
671 stats.decoding_normal = 67890;
672 stats.decoding_plc = 1234;
Alex Narest5b5d97c2019-08-07 18:15:08 +0200673 stats.decoding_codec_plc = 1236;
solenberg85a04962015-10-27 03:35:21 -0700674 stats.decoding_cng = 5678;
675 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700676 stats.decoding_muted_output = 3456;
677 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200678 return stats;
679 }
680 void SetAudioReceiveStreamStats() {
681 for (auto* s : call_.GetAudioReceiveStreams()) {
682 s->SetStats(GetAudioReceiveStreamStats());
683 }
684 }
685 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700686 const auto stats = GetAudioReceiveStreamStats();
687 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
688 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200689 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
690 stats.packets_rcvd);
691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
692 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700693 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800694 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
696 stats.ext_seqnum);
697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
699 stats.jitter_buffer_ms);
700 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700701 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200702 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
703 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700704 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700705 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
706 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200707 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200708 EXPECT_EQ(info.jitter_buffer_delay_seconds,
709 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100710 EXPECT_EQ(info.jitter_buffer_emitted_count,
711 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700712 EXPECT_EQ(info.expand_rate, stats.expand_rate);
713 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
714 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200715 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700716 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
717 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200718 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700719 stats.decoding_calls_to_silence_generator);
720 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
721 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
722 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
Alex Narest5b5d97c2019-08-07 18:15:08 +0200723 EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
solenberg85a04962015-10-27 03:35:21 -0700724 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
725 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700726 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700727 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200728 }
hbos1acfbd22016-11-17 23:43:29 -0800729 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
730 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
731 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
732 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
733 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
734 codec.ToCodecParameters());
735 }
736 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
737 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
738 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
739 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
740 codec.ToCodecParameters());
741 }
742 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200743
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100744 void VerifyGainControlEnabledCorrectly() {
745 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
746 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
747 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
748 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
749 }
750
751 void VerifyGainControlDefaultSettings() {
752 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
753 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
754 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
755 }
756
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200757 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100758 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200759 }
760
peah8271d042016-11-22 07:24:52 -0800761 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100762 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800763 }
764
Sam Zackrissonba502232019-01-04 10:36:48 +0100765 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100766 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100767 }
768
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769 protected:
Danil Chapovalov4c7112a2019-03-27 18:51:45 +0100770 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700771 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700772 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800773 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200774 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700775 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700776 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 cricket::AudioSendParameters send_parameters_;
778 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800779 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700780 webrtc::AudioProcessing::Config apm_config_;
781
stefanba4c0e42016-02-04 04:12:24 -0800782 private:
783 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784};
785
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100787TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
solenberg31fec402016-05-06 02:13:12 -0700791// Test that we can add a send stream and that it has the correct defaults.
792TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
793 EXPECT_TRUE(SetupChannel());
794 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800795 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
796 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
797 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700798 EXPECT_EQ("", config.rtp.c_name);
799 EXPECT_EQ(0u, config.rtp.extensions.size());
800 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
801 config.send_transport);
802}
803
804// Test that we can add a receive stream and that it has the correct defaults.
805TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
806 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800807 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700808 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800809 GetRecvStreamConfig(kSsrcX);
810 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700811 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
812 EXPECT_FALSE(config.rtp.transport_cc);
813 EXPECT_EQ(0u, config.rtp.extensions.size());
814 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
815 config.rtcp_send_transport);
816 EXPECT_EQ("", config.sync_group);
817}
818
stefanba4c0e42016-02-04 04:12:24 -0800819TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700820 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800821 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100822 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800823 if (codec.name == "opus") {
824 EXPECT_TRUE(HasTransportCc(codec));
825 opus_found = true;
826 }
827 }
828 EXPECT_TRUE(opus_found);
829}
830
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831// Test that we set our inbound codecs properly, including changing PT.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800837 parameters.codecs.push_back(kTelephoneEventCodec1);
838 parameters.codecs.push_back(kTelephoneEventCodec2);
839 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 parameters.codecs[2].id = 126;
841 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800842 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700843 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
844 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
845 {{0, {"PCMU", 8000, 1}},
846 {106, {"ISAC", 16000, 1}},
847 {126, {"telephone-event", 8000, 1}},
848 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849}
850
851// Test that we fail to set an unknown inbound codec.
852TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700853 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200854 cricket::AudioRecvParameters parameters;
855 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700856 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we fail if we have duplicate types in the inbound list.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kCn16000Codec);
866 parameters.codecs[1].id = kIsacCodec.id;
867 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868}
869
870// Test that we can decode OPUS without stereo parameters.
871TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700872 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200873 cricket::AudioRecvParameters parameters;
874 parameters.codecs.push_back(kIsacCodec);
875 parameters.codecs.push_back(kPcmuCodec);
876 parameters.codecs.push_back(kOpusCodec);
877 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800878 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700879 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
880 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
881 {{0, {"PCMU", 8000, 1}},
882 {103, {"ISAC", 16000, 1}},
883 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884}
885
886// Test that we can decode OPUS with stereo = 0.
887TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700888 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 cricket::AudioRecvParameters parameters;
890 parameters.codecs.push_back(kIsacCodec);
891 parameters.codecs.push_back(kPcmuCodec);
892 parameters.codecs.push_back(kOpusCodec);
893 parameters.codecs[2].params["stereo"] = "0";
894 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800895 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700896 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
897 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
898 {{0, {"PCMU", 8000, 1}},
899 {103, {"ISAC", 16000, 1}},
900 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
903// Test that we can decode OPUS with stereo = 1.
904TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700905 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200906 cricket::AudioRecvParameters parameters;
907 parameters.codecs.push_back(kIsacCodec);
908 parameters.codecs.push_back(kPcmuCodec);
909 parameters.codecs.push_back(kOpusCodec);
910 parameters.codecs[2].params["stereo"] = "1";
911 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800912 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700913 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
914 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
915 {{0, {"PCMU", 8000, 1}},
916 {103, {"ISAC", 16000, 1}},
917 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
920// Test that changes to recv codecs are applied to all streams.
921TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700922 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200923 cricket::AudioRecvParameters parameters;
924 parameters.codecs.push_back(kIsacCodec);
925 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800926 parameters.codecs.push_back(kTelephoneEventCodec1);
927 parameters.codecs.push_back(kTelephoneEventCodec2);
928 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 parameters.codecs[2].id = 126;
930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700931 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
932 EXPECT_TRUE(AddRecvStream(ssrc));
933 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
934 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
935 {{0, {"PCMU", 8000, 1}},
936 {106, {"ISAC", 16000, 1}},
937 {126, {"telephone-event", 8000, 1}},
938 {107, {"telephone-event", 32000, 1}}})));
939 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
942TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700943 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200944 cricket::AudioRecvParameters parameters;
945 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800946 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
solenberg2100c0b2017-03-01 11:29:29 -0800949 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200950 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800951 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
954// Test that we can apply the same set of codecs again while playing.
955TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 cricket::AudioRecvParameters parameters;
958 parameters.codecs.push_back(kIsacCodec);
959 parameters.codecs.push_back(kCn16000Codec);
960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700961 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
deadbeefcb383672017-04-26 16:28:42 -0700964 // Remapping a payload type to a different codec should fail.
965 parameters.codecs[0] = kOpusCodec;
966 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200967 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800968 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
971// Test that we can add a codec while playing.
972TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700973 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200974 cricket::AudioRecvParameters parameters;
975 parameters.codecs.push_back(kIsacCodec);
976 parameters.codecs.push_back(kCn16000Codec);
977 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700978 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200980 parameters.codecs.push_back(kOpusCodec);
981 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800982 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983}
984
deadbeefcb383672017-04-26 16:28:42 -0700985// Test that we accept adding the same codec with a different payload type.
986// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
987TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
988 EXPECT_TRUE(SetupRecvStream());
989 cricket::AudioRecvParameters parameters;
990 parameters.codecs.push_back(kIsacCodec);
991 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
992
993 ++parameters.codecs[0].id;
994 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
995}
996
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001000 // Test that when autobw is enabled, bitrate is kept as the default
1001 // value. autobw is enabled for the following tests because the target
1002 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003
1004 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001005 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006
1007 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001008 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009
ossu20a4b3f2017-04-27 02:08:52 -07001010 // opus, default bitrate == 32000 in mono.
1011 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012}
1013
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001014TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001015 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001018 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1019 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001020 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001023 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1024 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1025 // Rates above the max (510000) should be capped.
1026 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027}
1028
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001029TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001030 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001031
1032 // Test that we can only set a maximum bitrate for a fixed-rate codec
1033 // if it's bigger than the fixed rate.
1034
1035 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001036 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1037 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1038 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1039 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1040 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1041 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1042 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001043}
1044
1045TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001046 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001047 const int kDesiredBitrate = 128000;
1048 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001049 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001050 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001051 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001052
Yves Gerey665174f2018-06-19 15:03:05 +02001053 EXPECT_TRUE(
1054 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001055
solenberg2100c0b2017-03-01 11:29:29 -08001056 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001057}
1058
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059// Test that bitrate cannot be set for CBR codecs.
1060// Bitrate is ignored if it is higher than the fixed bitrate.
1061// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001062TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001063 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001064
1065 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001066 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001067 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001068
1069 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001070 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001072
1073 send_parameters_.max_bandwidth_bps = 128;
1074 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001076}
1077
skvlade0d46372016-04-07 22:59:22 -07001078// Test that the per-stream bitrate limit and the global
1079// bitrate limit both apply.
1080TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1081 EXPECT_TRUE(SetupSendStream());
1082
ossu20a4b3f2017-04-27 02:08:52 -07001083 // opus, default bitrate == 32000.
1084 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001085 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1086 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1087 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1088
1089 // CBR codecs allow both maximums to exceed the bitrate.
1090 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1091 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1092 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1093 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1094
1095 // CBR codecs don't allow per stream maximums to be too low.
1096 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1097 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1098}
1099
1100// Test that an attempt to set RtpParameters for a stream that does not exist
1101// fails.
1102TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1103 EXPECT_TRUE(SetupChannel());
1104 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001105 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001106 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001107
1108 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001109 EXPECT_FALSE(
1110 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001111}
1112
1113TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001114 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001115 // This test verifies that setting RtpParameters succeeds only if
1116 // the structure contains exactly one encoding.
1117 // TODO(skvlad): Update this test when we start supporting setting parameters
1118 // for each encoding individually.
1119
1120 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001122 // Two or more encodings should result in failure.
1123 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001124 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001125 // Zero encodings should also fail.
1126 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001127 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001128}
1129
1130// Changing the SSRC through RtpParameters is not allowed.
1131TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1132 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001134 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001135 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001136}
1137
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001138// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001140TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1141 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001142 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001143 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001145 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146 ASSERT_EQ(1u, parameters.encodings.size());
1147 ASSERT_TRUE(parameters.encodings[0].active);
1148 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001149 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001150 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001151
1152 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001153 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001154 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001155 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001156 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001157 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001158}
1159
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160// Test that SetRtpSendParameters configures the correct encoding channel for
1161// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001162TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1163 SetupForMultiSendStream();
1164 // Create send streams.
1165 for (uint32_t ssrc : kSsrcs4) {
1166 EXPECT_TRUE(
1167 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1168 }
1169 // Configure one stream to be limited by the stream config, another to be
1170 // limited by the global max, and the third one with no per-stream limit
1171 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001172 SetGlobalMaxBitrate(kOpusCodec, 32000);
1173 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1174 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001175 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1176
ossu20a4b3f2017-04-27 02:08:52 -07001177 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1178 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1179 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001180
1181 // Remove the global cap; the streams should switch to their respective
1182 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001183 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001184 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1185 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1186 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001187}
1188
Tim Haloun648d28a2018-10-18 16:52:22 -07001189// RTCRtpEncodingParameters.network_priority must be one of a few values
1190// derived from the default priority, corresponding to very-low, low, medium,
1191// or high.
1192TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1193 EXPECT_TRUE(SetupSendStream());
1194 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1195 EXPECT_EQ(1UL, parameters.encodings.size());
1196 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1197 parameters.encodings[0].network_priority);
1198
1199 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1200 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1201 for (auto it : good_values) {
1202 parameters.encodings[0].network_priority = it;
1203 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1204 }
1205 for (auto it : bad_values) {
1206 parameters.encodings[0].network_priority = it;
1207 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1208 }
1209}
1210
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001211// Test that GetRtpSendParameters returns the currently configured codecs.
1212TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001213 EXPECT_TRUE(SetupSendStream());
1214 cricket::AudioSendParameters parameters;
1215 parameters.codecs.push_back(kIsacCodec);
1216 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001217 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218
solenberg2100c0b2017-03-01 11:29:29 -08001219 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001220 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1222 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001223}
1224
Florent Castellidacec712018-05-24 16:24:21 +02001225// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1226TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1227 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1228 params.cname = "rtcpcname";
1229 EXPECT_TRUE(SetupSendStream(params));
1230
1231 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1232 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1233}
1234
Florent Castelliabe301f2018-06-12 18:33:49 +02001235TEST_F(WebRtcVoiceEngineTestFake,
1236 DetectRtpSendParameterHeaderExtensionsChange) {
1237 EXPECT_TRUE(SetupSendStream());
1238
1239 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1240 rtp_parameters.header_extensions.emplace_back();
1241
1242 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1243
1244 webrtc::RTCError result =
1245 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1246 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1247}
1248
deadbeefcb443432016-12-12 11:12:36 -08001249// Test that GetRtpSendParameters returns an SSRC.
1250TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1251 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001252 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001253 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001254 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001255}
1256
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001258TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001259 EXPECT_TRUE(SetupSendStream());
1260 cricket::AudioSendParameters parameters;
1261 parameters.codecs.push_back(kIsacCodec);
1262 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001263 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001264
solenberg2100c0b2017-03-01 11:29:29 -08001265 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001266
1267 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001268 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001269
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001270 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001271 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1272 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001273}
1274
minyuececec102017-03-27 13:04:25 -07001275// Test that max_bitrate_bps in send stream config gets updated correctly when
1276// SetRtpSendParameters is called.
1277TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1278 webrtc::test::ScopedFieldTrials override_field_trials(
1279 "WebRTC-Audio-SendSideBwe/Enabled/");
1280 EXPECT_TRUE(SetupSendStream());
1281 cricket::AudioSendParameters send_parameters;
1282 send_parameters.codecs.push_back(kOpusCodec);
1283 SetSendParameters(send_parameters);
1284
1285 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1286 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1287 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1288
1289 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001290 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001291 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001292
1293 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1294 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1295}
1296
Seth Hampson24722b32017-12-22 09:36:42 -08001297// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1298// a value <= 0, setting the parameters returns false.
1299TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1300 EXPECT_TRUE(SetupSendStream());
1301 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1302 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1303 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1304 rtp_parameters.encodings[0].bitrate_priority);
1305
1306 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001307 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001308 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001309 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001310}
1311
1312// Test that the bitrate_priority in the send stream config gets updated when
1313// SetRtpSendParameters is set for the VoiceMediaChannel.
1314TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1315 EXPECT_TRUE(SetupSendStream());
1316 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1317
1318 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1319 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1320 rtp_parameters.encodings[0].bitrate_priority);
1321 double new_bitrate_priority = 2.0;
1322 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001323 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001324
1325 // The priority should get set for both the audio channel's rtp parameters
1326 // and the audio send stream's audio config.
1327 EXPECT_EQ(
1328 new_bitrate_priority,
1329 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1330 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1331}
1332
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001333// Test that GetRtpReceiveParameters returns the currently configured codecs.
1334TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1335 EXPECT_TRUE(SetupRecvStream());
1336 cricket::AudioRecvParameters parameters;
1337 parameters.codecs.push_back(kIsacCodec);
1338 parameters.codecs.push_back(kPcmuCodec);
1339 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1340
1341 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001342 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001343 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1344 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1345 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1346}
1347
deadbeefcb443432016-12-12 11:12:36 -08001348// Test that GetRtpReceiveParameters returns an SSRC.
1349TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1350 EXPECT_TRUE(SetupRecvStream());
1351 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001352 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001353 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001354 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001355}
1356
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001357// Test that if we set/get parameters multiple times, we get the same results.
1358TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1359 EXPECT_TRUE(SetupRecvStream());
1360 cricket::AudioRecvParameters parameters;
1361 parameters.codecs.push_back(kIsacCodec);
1362 parameters.codecs.push_back(kPcmuCodec);
1363 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1364
1365 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001366 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001367
1368 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001369 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001370
1371 // ... And this shouldn't change the params returned by
1372 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001373 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1374 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001375}
1376
deadbeef3bc15102017-04-20 19:25:07 -07001377// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1378// aren't signaled. It should return an empty "RtpEncodingParameters" when
1379// configured to receive an unsignaled stream and no packets have been received
1380// yet, and start returning the SSRC once a packet has been received.
1381TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1382 ASSERT_TRUE(SetupChannel());
1383 // Call necessary methods to configure receiving a default stream as
1384 // soon as it arrives.
1385 cricket::AudioRecvParameters parameters;
1386 parameters.codecs.push_back(kIsacCodec);
1387 parameters.codecs.push_back(kPcmuCodec);
1388 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1389
1390 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1391 // stream. Should return nothing.
1392 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1393
1394 // Set a sink for an unsignaled stream.
1395 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1396 // Value of "0" means "unsignaled stream".
1397 channel_->SetRawAudioSink(0, std::move(fake_sink));
1398
1399 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1400 // in this method means "unsignaled stream".
1401 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1402 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1403 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1404
1405 // Receive PCMU packet (SSRC=1).
1406 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1407
1408 // The |ssrc| member should still be unset.
1409 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1410 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1411 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1412}
1413
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414// Test that we apply codecs properly.
1415TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001416 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 cricket::AudioSendParameters parameters;
1418 parameters.codecs.push_back(kIsacCodec);
1419 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001420 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001422 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1425 EXPECT_EQ(96, send_codec_spec.payload_type);
1426 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1427 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1428 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001429 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001430 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001431}
1432
ossu20a4b3f2017-04-27 02:08:52 -07001433// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1434// AudioSendStream.
1435TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 cricket::AudioSendParameters parameters;
1438 parameters.codecs.push_back(kIsacCodec);
1439 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001440 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 parameters.codecs[0].id = 96;
1442 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001443 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001446 // Calling SetSendCodec again with same codec which is already set.
1447 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001448 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001449 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001450}
1451
ossu20a4b3f2017-04-27 02:08:52 -07001452// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1453// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001454
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001455// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001457 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 cricket::AudioSendParameters parameters;
1459 parameters.codecs.push_back(kOpusCodec);
1460 parameters.codecs[0].bitrate = 0;
1461 parameters.codecs[0].clockrate = 50000;
1462 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001465// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 0;
1471 parameters.codecs[0].channels = 0;
1472 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001475// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001477 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001478 cricket::AudioSendParameters parameters;
1479 parameters.codecs.push_back(kOpusCodec);
1480 parameters.codecs[0].bitrate = 0;
1481 parameters.codecs[0].channels = 0;
1482 parameters.codecs[0].params["stereo"] = "1";
1483 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484}
1485
1486// Test that if channel is 1 for opus and there's no stereo, we fail.
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001488 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001489 cricket::AudioSendParameters parameters;
1490 parameters.codecs.push_back(kOpusCodec);
1491 parameters.codecs[0].bitrate = 0;
1492 parameters.codecs[0].channels = 1;
1493 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494}
1495
1496// Test that if channel is 1 for opus and stereo=0, we fail.
1497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].bitrate = 0;
1502 parameters.codecs[0].channels = 1;
1503 parameters.codecs[0].params["stereo"] = "0";
1504 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505}
1506
1507// Test that if channel is 1 for opus and stereo=1, we fail.
1508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].bitrate = 0;
1513 parameters.codecs[0].channels = 1;
1514 parameters.codecs[0].params["stereo"] = "1";
1515 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
ossu20a4b3f2017-04-27 02:08:52 -07001518// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 cricket::AudioSendParameters parameters;
1522 parameters.codecs.push_back(kOpusCodec);
1523 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001525 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001526}
1527
ossu20a4b3f2017-04-27 02:08:52 -07001528// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001530 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 cricket::AudioSendParameters parameters;
1532 parameters.codecs.push_back(kOpusCodec);
1533 parameters.codecs[0].bitrate = 0;
1534 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001535 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001536 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001537}
1538
ossu20a4b3f2017-04-27 02:08:52 -07001539// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001540TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001541 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001542 cricket::AudioSendParameters parameters;
1543 parameters.codecs.push_back(kOpusCodec);
1544 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001545 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001547 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001548 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001549
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001551 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001552 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001553}
1554
ossu20a4b3f2017-04-27 02:08:52 -07001555// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001557 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 cricket::AudioSendParameters parameters;
1559 parameters.codecs.push_back(kOpusCodec);
1560 parameters.codecs[0].bitrate = 0;
1561 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001563 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
ossu20a4b3f2017-04-27 02:08:52 -07001566// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kOpusCodec);
1571 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001572 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001575 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001576
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001579 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001580}
1581
ossu20a4b3f2017-04-27 02:08:52 -07001582// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001584 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001588 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001589 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1590 EXPECT_EQ(111, spec.payload_type);
1591 EXPECT_EQ(96000, spec.target_bitrate_bps);
1592 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001593 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001594 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595}
1596
ossu20a4b3f2017-04-27 02:08:52 -07001597// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kOpusCodec);
1602 parameters.codecs[0].bitrate = 30000;
1603 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001605 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606}
1607
ossu20a4b3f2017-04-27 02:08:52 -07001608// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001609TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001610 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001611 cricket::AudioSendParameters parameters;
1612 parameters.codecs.push_back(kOpusCodec);
1613 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001614 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001615 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616}
1617
ossu20a4b3f2017-04-27 02:08:52 -07001618// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001620 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001621 cricket::AudioSendParameters parameters;
1622 parameters.codecs.push_back(kOpusCodec);
1623 parameters.codecs[0].bitrate = 30000;
1624 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001626 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001627}
1628
stefan13f1a0a2016-11-30 07:22:58 -08001629TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1630 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1631 200000);
1632}
1633
1634TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1635 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1636}
1637
1638TEST_F(WebRtcVoiceEngineTestFake,
1639 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1640 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1641}
1642
1643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1644 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1645}
1646
Yves Gerey665174f2018-06-19 15:03:05 +02001647TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001648 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1649 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001650 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001651 // Setting max bitrate should keep previous min bitrate
1652 // Setting max bitrate should not reset start bitrate.
1653 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1654 SetSdpBitrateParameters(
1655 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1656 Field(&BitrateConstraints::start_bitrate_bps, -1),
1657 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001658 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001659}
1660
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001661// Test that we can enable NACK with opus as callee.
1662TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001663 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 cricket::AudioSendParameters parameters;
1665 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001666 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1667 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001668 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001669 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001670 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001671 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001672
Yves Gerey665174f2018-06-19 15:03:05 +02001673 EXPECT_TRUE(
1674 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001675}
1676
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677// Test that we can enable NACK on receive streams.
1678TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001679 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 cricket::AudioSendParameters parameters;
1682 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001683 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1684 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001685 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001687 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688}
1689
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690// Test that we can disable NACK on receive streams.
1691TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001692 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 cricket::AudioSendParameters parameters;
1695 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001696 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1697 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001701 parameters.codecs.clear();
1702 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001704 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705}
1706
1707// Test that NACK is enabled on a new receive stream.
1708TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001709 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 cricket::AudioSendParameters parameters;
1711 parameters.codecs.push_back(kIsacCodec);
1712 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001713 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1714 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716
solenberg2100c0b2017-03-01 11:29:29 -08001717 EXPECT_TRUE(AddRecvStream(kSsrcY));
1718 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1719 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1720 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721}
1722
stefanba4c0e42016-02-04 04:12:24 -08001723TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001725 cricket::AudioSendParameters send_parameters;
1726 send_parameters.codecs.push_back(kOpusCodec);
1727 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001729
1730 cricket::AudioRecvParameters recv_parameters;
1731 recv_parameters.codecs.push_back(kIsacCodec);
1732 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001733 EXPECT_TRUE(AddRecvStream(kSsrcX));
1734 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001735 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001736 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001737
ossudedfd282016-06-14 07:12:39 -07001738 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001740 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001741 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001742 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001743}
1744
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001745// Test that we can switch back and forth between Opus and ISAC with CN.
1746TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001747 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001748
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters opus_parameters;
1750 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001752 {
ossu20a4b3f2017-04-27 02:08:52 -07001753 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1754 EXPECT_EQ(111, spec.payload_type);
1755 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001756 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 cricket::AudioSendParameters isac_parameters;
1759 isac_parameters.codecs.push_back(kIsacCodec);
1760 isac_parameters.codecs.push_back(kCn16000Codec);
1761 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(103, spec.payload_type);
1766 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001767 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001770 {
ossu20a4b3f2017-04-27 02:08:52 -07001771 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1772 EXPECT_EQ(111, spec.payload_type);
1773 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001774 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775}
1776
1777// Test that we handle various ways of specifying bitrate.
1778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001779 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001780 cricket::AudioSendParameters parameters;
1781 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001783 {
ossu20a4b3f2017-04-27 02:08:52 -07001784 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1785 EXPECT_EQ(103, spec.payload_type);
1786 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1787 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001788 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789
Yves Gerey665174f2018-06-19 15:03:05 +02001790 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 {
ossu20a4b3f2017-04-27 02:08:52 -07001793 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1794 EXPECT_EQ(103, spec.payload_type);
1795 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1796 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001797 }
Yves Gerey665174f2018-06-19 15:03:05 +02001798 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001799 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001800 {
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(103, spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1804 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001805 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806
Yves Gerey665174f2018-06-19 15:03:05 +02001807 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001808 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001809 {
ossu20a4b3f2017-04-27 02:08:52 -07001810 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1811 EXPECT_EQ(0, spec.payload_type);
1812 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1813 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001814 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815
Yves Gerey665174f2018-06-19 15:03:05 +02001816 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001818 {
ossu20a4b3f2017-04-27 02:08:52 -07001819 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1820 EXPECT_EQ(0, spec.payload_type);
1821 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1822 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001823 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001826 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001827 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001828 {
ossu20a4b3f2017-04-27 02:08:52 -07001829 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1830 EXPECT_EQ(111, spec.payload_type);
1831 EXPECT_STREQ("opus", spec.format.name.c_str());
1832 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001833 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001834}
1835
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001836// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
1840 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001841}
1842
1843// Test that we can set send codecs even with telephone-event codec as the first
1844// one on the list.
1845TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001846 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001848 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001849 parameters.codecs.push_back(kIsacCodec);
1850 parameters.codecs.push_back(kPcmuCodec);
1851 parameters.codecs[0].id = 98; // DTMF
1852 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001854 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1855 EXPECT_EQ(96, spec.payload_type);
1856 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001857 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001858 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001859}
1860
Harald Alvestranda1f66612018-02-21 11:24:23 +01001861// Test that CanInsertDtmf() is governed by the send flag
1862TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1863 EXPECT_TRUE(SetupSendStream());
1864 cricket::AudioSendParameters parameters;
1865 parameters.codecs.push_back(kTelephoneEventCodec1);
1866 parameters.codecs.push_back(kPcmuCodec);
1867 parameters.codecs[0].id = 98; // DTMF
1868 parameters.codecs[1].id = 96;
1869 SetSendParameters(parameters);
1870 EXPECT_FALSE(channel_->CanInsertDtmf());
1871 SetSend(true);
1872 EXPECT_TRUE(channel_->CanInsertDtmf());
1873 SetSend(false);
1874 EXPECT_FALSE(channel_->CanInsertDtmf());
1875}
1876
solenberg31642aa2016-03-14 08:00:37 -07001877// Test that payload type range is limited for telephone-event codec.
1878TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001879 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001880 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001881 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs[0].id = 0; // DTMF
1884 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001885 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001886 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001887 EXPECT_TRUE(channel_->CanInsertDtmf());
1888 parameters.codecs[0].id = 128; // DTMF
1889 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1890 EXPECT_FALSE(channel_->CanInsertDtmf());
1891 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001893 EXPECT_TRUE(channel_->CanInsertDtmf());
1894 parameters.codecs[0].id = -1; // DTMF
1895 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1896 EXPECT_FALSE(channel_->CanInsertDtmf());
1897}
1898
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001899// Test that we can set send codecs even with CN codec as the first
1900// one on the list.
1901TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001902 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001903 cricket::AudioSendParameters parameters;
1904 parameters.codecs.push_back(kCn16000Codec);
1905 parameters.codecs.push_back(kIsacCodec);
1906 parameters.codecs.push_back(kPcmuCodec);
1907 parameters.codecs[0].id = 98; // wideband CN
1908 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001909 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001910 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1911 EXPECT_EQ(96, send_codec_spec.payload_type);
1912 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001913 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001914}
1915
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001916// Test that we set VAD and DTMF types correctly as caller.
1917TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001918 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001919 cricket::AudioSendParameters parameters;
1920 parameters.codecs.push_back(kIsacCodec);
1921 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001922 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 parameters.codecs.push_back(kCn16000Codec);
1924 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001925 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001926 parameters.codecs[0].id = 96;
1927 parameters.codecs[2].id = 97; // wideband CN
1928 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001929 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001930 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1931 EXPECT_EQ(96, send_codec_spec.payload_type);
1932 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001933 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001934 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001935 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001936 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937}
1938
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001939// Test that we set VAD and DTMF types correctly as callee.
1940TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001941 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001942 cricket::AudioSendParameters parameters;
1943 parameters.codecs.push_back(kIsacCodec);
1944 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001945 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001946 parameters.codecs.push_back(kCn16000Codec);
1947 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001948 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[0].id = 96;
1950 parameters.codecs[2].id = 97; // wideband CN
1951 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001952 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001953 EXPECT_TRUE(
1954 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001955
ossu20a4b3f2017-04-27 02:08:52 -07001956 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1957 EXPECT_EQ(96, send_codec_spec.payload_type);
1958 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001959 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001960 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001961 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001962 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001963}
1964
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965// Test that we only apply VAD if we have a CN codec that matches the
1966// send codec clockrate.
1967TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001968 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001970 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001971 parameters.codecs.push_back(kIsacCodec);
1972 parameters.codecs.push_back(kCn16000Codec);
1973 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001974 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001975 {
ossu20a4b3f2017-04-27 02:08:52 -07001976 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1977 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001978 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001979 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001980 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001981 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001984 {
ossu20a4b3f2017-04-27 02:08:52 -07001985 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1986 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001987 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001988 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001989 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001992 {
ossu20a4b3f2017-04-27 02:08:52 -07001993 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1994 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001995 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001996 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001997 }
Brave Yao5225dd82015-03-26 07:39:19 +08001998 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002001 {
ossu20a4b3f2017-04-27 02:08:52 -07002002 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2003 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002004 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07002005 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002006}
2007
2008// Test that we perform case-insensitive matching of codec names.
2009TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002010 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 cricket::AudioSendParameters parameters;
2012 parameters.codecs.push_back(kIsacCodec);
2013 parameters.codecs.push_back(kPcmuCodec);
2014 parameters.codecs.push_back(kCn16000Codec);
2015 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002016 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002017 parameters.codecs[0].name = "iSaC";
2018 parameters.codecs[0].id = 96;
2019 parameters.codecs[2].id = 97; // wideband CN
2020 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002021 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002022 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2023 EXPECT_EQ(96, send_codec_spec.payload_type);
2024 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002025 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002026 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002027 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002028 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002029}
2030
stefanba4c0e42016-02-04 04:12:24 -08002031class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2032 public:
2033 WebRtcVoiceEngineWithSendSideBweTest()
2034 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2035};
2036
2037TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2038 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002039 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2040 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002041 Contains(::testing::Field(
Elad Alon157540a2019-02-08 23:37:52 +01002042 "uri", &RtpExtension::uri,
2043 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002044}
2045
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002046// Test support for audio level header extension.
2047TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002048 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002049}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002050TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002051 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002052}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002053
solenbergd4adce42016-11-17 06:26:52 -08002054// Test support for transport sequence number header extension.
2055TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2056 TestSetSendRtpHeaderExtensions(
2057 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002058}
solenbergd4adce42016-11-17 06:26:52 -08002059TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2060 TestSetRecvRtpHeaderExtensions(
2061 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002062}
2063
solenberg1ac56142015-10-13 03:58:19 -07002064// Test that we can create a channel and start sending on it.
2065TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002066 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(send_parameters_);
2068 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002070 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002072}
2073
2074// Test that a channel will send if and only if it has a source and is enabled
2075// for sending.
2076TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002078 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002079 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002080 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2082 SetAudioSend(kSsrcX, true, &fake_source_);
2083 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2084 SetAudioSend(kSsrcX, true, nullptr);
2085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002086}
2087
solenberg94218532016-06-16 10:53:22 -07002088// Test that a channel is muted/unmuted.
2089TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2090 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002091 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002092 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2093 SetAudioSend(kSsrcX, true, nullptr);
2094 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2095 SetAudioSend(kSsrcX, false, nullptr);
2096 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002097}
2098
solenberg6d6e7c52016-04-13 09:07:30 -07002099// Test that SetSendParameters() does not alter a stream's send state.
2100TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2101 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002102 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002103
2104 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002105 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002106 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002107
2108 // Changing RTP header extensions will recreate the AudioSendStream.
2109 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002110 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002111 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002113
2114 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002115 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002117
2118 // Changing RTP header extensions will recreate the AudioSendStream.
2119 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002121 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002122}
2123
solenberg1ac56142015-10-13 03:58:19 -07002124// Test that we can create a channel and start playing out on it.
2125TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002126 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002127 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002128 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002130 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002131 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132}
2133
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134// Test that we can add and remove send streams.
2135TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2136 SetupForMultiSendStream();
2137
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002139 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140
solenbergc96df772015-10-21 13:01:53 -07002141 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002142 EXPECT_TRUE(
2143 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002144 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002146 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147 }
tfarina5237aaf2015-11-10 23:44:30 -08002148 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149
solenbergc96df772015-10-21 13:01:53 -07002150 // Delete the send streams.
2151 for (uint32_t ssrc : kSsrcs4) {
2152 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002153 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002154 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 }
solenbergc96df772015-10-21 13:01:53 -07002156 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157}
2158
2159// Test SetSendCodecs correctly configure the codecs in all send streams.
2160TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2161 SetupForMultiSendStream();
2162
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002164 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002165 EXPECT_TRUE(
2166 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002167 }
2168
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002171 parameters.codecs.push_back(kIsacCodec);
2172 parameters.codecs.push_back(kCn16000Codec);
2173 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002174 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175
2176 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002177 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002178 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2179 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002180 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2181 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002182 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002183 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002184 }
2185
minyue7a973442016-10-20 03:27:12 -07002186 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002187 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002188 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002189 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002190 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2191 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002192 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2193 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002194 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195 }
2196}
2197
2198// Test we can SetSend on all send streams correctly.
2199TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2200 SetupForMultiSendStream();
2201
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002203 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002204 EXPECT_TRUE(
2205 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002206 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002207 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 }
2209
2210 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002211 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002212 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002214 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215 }
2216
2217 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002218 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002219 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002221 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002222 }
2223}
2224
2225// Test we can set the correct statistics on all send streams.
2226TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2227 SetupForMultiSendStream();
2228
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002229 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002230 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002231 EXPECT_TRUE(
2232 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002233 }
solenberg85a04962015-10-27 03:35:21 -07002234
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002235 // Create a receive stream to check that none of the send streams end up in
2236 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002238
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002239 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002240 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002241 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002242 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002243
solenberg85a04962015-10-27 03:35:21 -07002244 // Check stats for the added streams.
2245 {
2246 cricket::VoiceMediaInfo info;
2247 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002248
solenberg85a04962015-10-27 03:35:21 -07002249 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002250 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002251 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002252 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002253 }
hbos1acfbd22016-11-17 23:43:29 -08002254 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002255
2256 // We have added one receive stream. We should see empty stats.
2257 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002258 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002259 }
solenberg1ac56142015-10-13 03:58:19 -07002260
solenberg2100c0b2017-03-01 11:29:29 -08002261 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002262 {
2263 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002265 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002266 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002267 EXPECT_EQ(0u, info.receivers.size());
2268 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002269
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002270 // Deliver a new packet - a default receive stream should be created and we
2271 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002272 {
2273 cricket::VoiceMediaInfo info;
2274 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2275 SetAudioReceiveStreamStats();
2276 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002277 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002278 EXPECT_EQ(1u, info.receivers.size());
2279 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002280 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002281 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002282}
2283
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002284// Test that we can add and remove receive streams, and do proper send/playout.
2285// We can receive on multiple streams while sending one stream.
2286TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002287 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288
solenberg1ac56142015-10-13 03:58:19 -07002289 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002290 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002291 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
solenberg1ac56142015-10-13 03:58:19 -07002293 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002294 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002295 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002296 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002297
solenberg1ac56142015-10-13 03:58:19 -07002298 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300
2301 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002302 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2303 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2304 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002305
2306 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002307 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002308 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002309
2310 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002311 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002312 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2313 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002314
aleloi84ef6152016-08-04 05:28:21 -07002315 // Restart playout and make sure recv streams are played out.
2316 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002317 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2318 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002319
aleloi84ef6152016-08-04 05:28:21 -07002320 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002321 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2322 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323}
2324
wu@webrtc.org97077a32013-10-25 21:18:33 +00002325TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002326 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002327 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002328 .Times(::testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002329 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002330 const auto& agc_config = apm_config_.gain_controller1;
2331
2332 // Ensure default options.
2333 VerifyGainControlEnabledCorrectly();
2334 VerifyGainControlDefaultSettings();
2335
2336 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002337 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002338 EXPECT_FALSE(agc_config.enabled);
2339 send_parameters_.options.auto_gain_control = absl::nullopt;
2340
2341 send_parameters_.options.tx_agc_target_dbov = 5;
2342 SetSendParameters(send_parameters_);
2343 EXPECT_EQ(5, agc_config.target_level_dbfs);
2344 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2345
2346 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2347 SetSendParameters(send_parameters_);
2348 EXPECT_EQ(10, agc_config.compression_gain_db);
2349 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2350
2351 send_parameters_.options.tx_agc_limiter = false;
2352 SetSendParameters(send_parameters_);
2353 EXPECT_FALSE(agc_config.enable_limiter);
2354 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2355
2356 SetSendParameters(send_parameters_);
2357 // Expect all options to have been preserved.
2358 EXPECT_FALSE(agc_config.enabled);
2359 EXPECT_EQ(5, agc_config.target_level_dbfs);
2360 EXPECT_EQ(10, agc_config.compression_gain_db);
2361 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002362}
2363
minyue6b825df2016-10-31 04:08:32 -07002364TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2365 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002366 send_parameters_.options.audio_network_adaptor = true;
2367 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002368 SetSendParameters(send_parameters_);
2369 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002370 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002371}
2372
2373TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2374 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002375 send_parameters_.options.audio_network_adaptor = true;
2376 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002377 SetSendParameters(send_parameters_);
2378 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002379 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002380 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002381 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002382 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002383 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002384}
2385
2386TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2387 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002388 send_parameters_.options.audio_network_adaptor = true;
2389 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002390 SetSendParameters(send_parameters_);
2391 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002392 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002393 const int initial_num = call_.GetNumCreatedSendStreams();
2394 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002395 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002396 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2397 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002398 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002399 // AudioSendStream not expected to be recreated.
2400 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2401 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002402 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002403}
2404
michaelt6672b262017-01-11 10:17:59 -08002405class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2406 : public WebRtcVoiceEngineTestFake {
2407 public:
2408 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2409 : WebRtcVoiceEngineTestFake(
Daniel Lee93562522019-05-03 14:40:13 +02002410 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-Audio-Allocation/"
2411 "min:6000bps,max:32000bps/WebRTC-SendSideBwe-WithOverhead/"
michaelt6672b262017-01-11 10:17:59 -08002412 "Enabled/") {}
2413};
2414
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002416// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002418 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002419 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420}
2421
2422TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2423 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002424 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002425 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002426 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002427 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002428 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002429 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002430 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431
solenberg85a04962015-10-27 03:35:21 -07002432 // Check stats for the added streams.
2433 {
2434 cricket::VoiceMediaInfo info;
2435 EXPECT_EQ(true, channel_->GetStats(&info));
2436
2437 // We have added one send stream. We should see the stats we've set.
2438 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002439 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002440 // We have added one receive stream. We should see empty stats.
2441 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002442 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002443 }
solenberg1ac56142015-10-13 03:58:19 -07002444
solenberg566ef242015-11-06 15:34:49 -08002445 // Start sending - this affects some reported stats.
2446 {
2447 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002448 SetSend(true);
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));
solenberg85a04962015-10-27 03:35:21 -07002458 EXPECT_EQ(true, channel_->GetStats(&info));
2459 EXPECT_EQ(1u, info.senders.size());
2460 EXPECT_EQ(0u, info.receivers.size());
2461 }
solenberg1ac56142015-10-13 03:58:19 -07002462
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002463 // Deliver a new packet - a default receive stream should be created and we
2464 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002465 {
2466 cricket::VoiceMediaInfo info;
2467 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2468 SetAudioReceiveStreamStats();
2469 EXPECT_EQ(true, channel_->GetStats(&info));
2470 EXPECT_EQ(1u, info.senders.size());
2471 EXPECT_EQ(1u, info.receivers.size());
2472 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002473 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002474 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475}
2476
2477// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002478// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002480 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2482 EXPECT_TRUE(AddRecvStream(kSsrcY));
2483 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484}
2485
2486// Test that the local SSRC is the same on sending and receiving channels if the
2487// receive channel is created before the send channel.
2488TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002489 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002490 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002491 EXPECT_TRUE(
2492 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002493 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2494 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495}
2496
2497// Test that we can properly receive packets.
2498TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002499 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002500 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002502
Yves Gerey665174f2018-06-19 15:03:05 +02002503 EXPECT_TRUE(
2504 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505}
2506
2507// Test that we can properly receive packets on multiple streams.
2508TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002509 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002510 const uint32_t ssrc1 = 1;
2511 const uint32_t ssrc2 = 2;
2512 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002513 EXPECT_TRUE(AddRecvStream(ssrc1));
2514 EXPECT_TRUE(AddRecvStream(ssrc2));
2515 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002516 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002517 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002518 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002520 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002521 }
mflodman3d7db262016-04-29 00:57:13 -07002522
2523 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2524 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2525 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2526
2527 EXPECT_EQ(s1.received_packets(), 0);
2528 EXPECT_EQ(s2.received_packets(), 0);
2529 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002530
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002532 EXPECT_EQ(s1.received_packets(), 0);
2533 EXPECT_EQ(s2.received_packets(), 0);
2534 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002535
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002536 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002537 EXPECT_EQ(s1.received_packets(), 1);
2538 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2539 EXPECT_EQ(s2.received_packets(), 0);
2540 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002541
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002543 EXPECT_EQ(s1.received_packets(), 1);
2544 EXPECT_EQ(s2.received_packets(), 1);
2545 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2546 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002547
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002549 EXPECT_EQ(s1.received_packets(), 1);
2550 EXPECT_EQ(s2.received_packets(), 1);
2551 EXPECT_EQ(s3.received_packets(), 1);
2552 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002553
mflodman3d7db262016-04-29 00:57:13 -07002554 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2555 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2556 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557}
2558
solenberg2100c0b2017-03-01 11:29:29 -08002559// Test that receiving on an unsignaled stream works (a stream is created).
2560TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002561 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002562 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002563
solenberg7e63ef02015-11-20 00:19:43 -08002564 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002565
Mirko Bonadeif859e552018-05-30 15:31:29 +02002566 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002567 EXPECT_TRUE(
2568 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002569}
2570
Seth Hampson5897a6e2018-04-03 11:16:33 -07002571// Tests that when we add a stream without SSRCs, but contains a stream_id
2572// that it is stored and its stream id is later used when the first packet
2573// arrives to properly create a receive stream with a sync label.
2574TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2575 const char kSyncLabel[] = "sync_label";
2576 EXPECT_TRUE(SetupChannel());
2577 cricket::StreamParams unsignaled_stream;
2578 unsignaled_stream.set_stream_ids({kSyncLabel});
2579 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2580 // The stream shouldn't have been created at this point because it doesn't
2581 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002582 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002583
2584 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2585
Mirko Bonadeif859e552018-05-30 15:31:29 +02002586 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002587 EXPECT_TRUE(
2588 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2589 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2590
2591 // Removing the unsignaled stream clears the cached parameters. If a new
2592 // default unsignaled receive stream is created it will not have a sync group.
2593 channel_->RemoveRecvStream(0);
2594 channel_->RemoveRecvStream(kSsrc1);
2595
2596 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2597
Mirko Bonadeif859e552018-05-30 15:31:29 +02002598 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002599 EXPECT_TRUE(
2600 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2601 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2602}
2603
solenberg2100c0b2017-03-01 11:29:29 -08002604// Test that receiving N unsignaled stream works (streams will be created), and
2605// that packets are forwarded to them all.
2606TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002607 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002608 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002609 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2610
solenberg2100c0b2017-03-01 11:29:29 -08002611 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002612 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002613 rtc::SetBE32(&packet[8], ssrc);
2614 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002615
solenberg2100c0b2017-03-01 11:29:29 -08002616 // Verify we have one new stream for each loop iteration.
2617 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002618 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2619 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002620 }
mflodman3d7db262016-04-29 00:57:13 -07002621
solenberg2100c0b2017-03-01 11:29:29 -08002622 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002623 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002624 rtc::SetBE32(&packet[8], ssrc);
2625 DeliverPacket(packet, sizeof(packet));
2626
solenbergebb349d2017-03-13 05:46:15 -07002627 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002628 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2629 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2630 }
2631
2632 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2633 constexpr uint32_t kAnotherSsrc = 667;
2634 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002635 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002636
2637 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002638 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002639 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002640 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002641 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2642 EXPECT_EQ(2, streams[i]->received_packets());
2643 }
2644 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2645 EXPECT_EQ(1, streams[i]->received_packets());
2646 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002647 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002648}
2649
solenberg2100c0b2017-03-01 11:29:29 -08002650// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002651// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002652TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002653 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002654 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002655 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2656
2657 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002658 const uint32_t signaled_ssrc = 1;
2659 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002660 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002661 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002662 EXPECT_TRUE(
2663 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002664 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002665
2666 // Note that the first unknown SSRC cannot be 0, because we only support
2667 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002668 const uint32_t unsignaled_ssrc = 7011;
2669 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002670 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002671 EXPECT_TRUE(
2672 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002673 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002674
2675 DeliverPacket(packet, sizeof(packet));
2676 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2677
2678 rtc::SetBE32(&packet[8], signaled_ssrc);
2679 DeliverPacket(packet, sizeof(packet));
2680 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002681 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002682}
2683
solenberg4904fb62017-02-17 12:01:14 -08002684// Two tests to verify that adding a receive stream with the same SSRC as a
2685// previously added unsignaled stream will only recreate underlying stream
2686// objects if the stream parameters have changed.
2687TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2688 EXPECT_TRUE(SetupChannel());
2689
2690 // Spawn unsignaled stream with SSRC=1.
2691 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002692 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002693 EXPECT_TRUE(
2694 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002695
2696 // Verify that the underlying stream object in Call is not recreated when a
2697 // stream with SSRC=1 is added.
2698 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002699 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002700 int audio_receive_stream_id = streams.front()->id();
2701 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002702 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002703 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2704}
2705
2706TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2707 EXPECT_TRUE(SetupChannel());
2708
2709 // Spawn unsignaled stream with SSRC=1.
2710 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002711 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002712 EXPECT_TRUE(
2713 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002714
2715 // Verify that the underlying stream object in Call *is* recreated when a
2716 // stream with SSRC=1 is added, and which has changed stream parameters.
2717 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002718 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002719 int audio_receive_stream_id = streams.front()->id();
2720 cricket::StreamParams stream_params;
2721 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002722 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002723 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002724 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002725 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2726}
2727
solenberg1ac56142015-10-13 03:58:19 -07002728// Test that AddRecvStream creates new stream.
2729TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002730 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002731 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732}
2733
2734// Test that after adding a recv stream, we do not decode more codecs than
2735// those previously passed into SetRecvCodecs.
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002738 cricket::AudioRecvParameters parameters;
2739 parameters.codecs.push_back(kIsacCodec);
2740 parameters.codecs.push_back(kPcmuCodec);
2741 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002742 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002743 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2744 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2745 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746}
2747
2748// Test that we properly clean up any streams that were added, even if
2749// not explicitly removed.
2750TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002751 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002753 EXPECT_TRUE(AddRecvStream(1));
2754 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002755
Mirko Bonadeif859e552018-05-30 15:31:29 +02002756 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2757 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758 delete channel_;
2759 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002760 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2761 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762}
2763
wu@webrtc.org78187522013-10-07 23:32:02 +00002764TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002765 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002766 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002767}
2768
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002769TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002770 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002771 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002772 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002773}
2774
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002775// Test the InsertDtmf on default send stream as caller.
2776TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002777 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002778}
2779
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002780// Test the InsertDtmf on default send stream as callee
2781TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002782 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002783}
2784
2785// Test the InsertDtmf on specified send stream as caller.
2786TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002787 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002788}
2789
2790// Test the InsertDtmf on specified send stream as callee.
2791TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002792 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793}
2794
Johannes Kron9190b822018-10-29 11:22:05 +01002795// Test propagation of extmap allow mixed setting.
2796TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2797 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2798}
2799TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2800 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2801}
2802TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2803 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2804}
2805TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2806 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2807}
2808
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002809TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002810 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002811 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002812 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
Per Åhgrenf40a3402019-04-25 08:50:11 +02002813 .Times(8)
Yves Gerey665174f2018-06-19 15:03:05 +02002814 .WillRepeatedly(Return(false));
2815 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2816 .Times(4)
2817 .WillRepeatedly(Return(false));
2818 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2819 .Times(2)
2820 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002821
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002822 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002823 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824
solenberg246b8172015-12-08 09:50:23 -08002825 // Nothing set in AudioOptions, so everything should be as default.
2826 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002827 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002828 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002829 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002830 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002831 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002832 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002833
Sam Zackrissonba502232019-01-04 10:36:48 +01002834 // Turn typing detection off.
2835 send_parameters_.options.typing_detection = false;
2836 SetSendParameters(send_parameters_);
2837 EXPECT_FALSE(IsTypingDetectionEnabled());
2838
2839 // Leave typing detection unchanged, but non-default.
2840 send_parameters_.options.typing_detection = absl::nullopt;
2841 SetSendParameters(send_parameters_);
2842 EXPECT_FALSE(IsTypingDetectionEnabled());
2843
2844 // Turn typing detection on.
2845 send_parameters_.options.typing_detection = true;
2846 SetSendParameters(send_parameters_);
2847 EXPECT_TRUE(IsTypingDetectionEnabled());
2848
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002850 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002851 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002852 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // Turn echo cancellation back on, with settings, and make sure
2855 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002856 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002857 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002858 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002860 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002861 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002862 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002863 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002864
Per Åhgrenf40a3402019-04-25 08:50:11 +02002865 // Restore AEC to be on to work with the following tests.
2866 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002867 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002868
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002870 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002871 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002872 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002873 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
2875 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002876 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002877 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002878 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002879 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002880
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002881 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002882 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002884 send_parameters_.options.noise_suppression = false;
2885 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002886 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002887 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002888 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002889 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002890 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
solenberg1ac56142015-10-13 03:58:19 -07002892 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002893 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002894 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002895 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002896 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002897 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898}
2899
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002901 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002902 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2903 .Times(8)
2904 .WillRepeatedly(Return(false));
2905 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2906 .Times(8)
2907 .WillRepeatedly(Return(false));
2908 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2909 .Times(8)
2910 .WillRepeatedly(Return(false));
2911 EXPECT_CALL(adm_, RecordingIsInitialized())
2912 .Times(2)
2913 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002914 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2915 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002916 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002917
kwiberg686a8ef2016-02-26 03:00:35 -08002918 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002919 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2920 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2921 cricket::AudioOptions(),
2922 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002923 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002924 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2925 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2926 cricket::AudioOptions(),
2927 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928
2929 // Have to add a stream to make SetSend work.
2930 cricket::StreamParams stream1;
2931 stream1.ssrcs.push_back(1);
2932 channel1->AddSendStream(stream1);
2933 cricket::StreamParams stream2;
2934 stream2.ssrcs.push_back(2);
2935 channel2->AddSendStream(stream2);
2936
2937 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002938 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002939 parameters_options_all.options.echo_cancellation = true;
2940 parameters_options_all.options.auto_gain_control = true;
2941 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002942 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002943 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002944 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002945 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002946 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002947 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002948 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002949 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002950 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002951 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952
2953 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002954 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002955 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002956 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002957 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002958 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002959 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002960 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002961 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002962 expected_options.echo_cancellation = true;
2963 expected_options.auto_gain_control = true;
2964 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002965 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002966
2967 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002968 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002969 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002970 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002972 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002973 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002974 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01002975 expected_options.echo_cancellation = true;
2976 expected_options.auto_gain_control = false;
2977 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002978 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002980 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002981 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002982 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002983 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002984 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002986 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002987 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002988 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002989 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002990 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002992 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002993 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002994 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002995 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002996 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002999 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3000 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003001 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3002 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003003 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003004 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003005 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003006 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003007 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003008 expected_options.echo_cancellation = true;
3009 expected_options.auto_gain_control = false;
3010 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003011 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012}
3013
wu@webrtc.orgde305012013-10-31 15:40:38 +00003014// This test verifies DSCP settings are properly applied on voice media channel.
3015TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003016 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003017 cricket::FakeNetworkInterface network_interface;
3018 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003019 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003020 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003021
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003022 EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003023
Sebastian Jansson84848f22018-11-16 10:40:36 +01003024 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3025 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3026 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003027 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003028 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3029 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3030
3031 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003032 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3033 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3034 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003035 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07003036 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3037
3038 // Create a send stream to configure
3039 EXPECT_TRUE(
3040 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3041 parameters = channel->GetRtpSendParameters(kSsrcZ);
3042 ASSERT_FALSE(parameters.encodings.empty());
3043
3044 // Various priorities map to various dscp values.
3045 parameters.encodings[0].network_priority = 4.0;
3046 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003047 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003048 parameters.encodings[0].network_priority = 0.5;
3049 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3050 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3051
3052 // A bad priority does not change the dscp value.
3053 parameters.encodings[0].network_priority = 0.0;
3054 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3055 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003056
Tim Haloun6ca98362018-09-17 17:06:08 -07003057 // Packets should also self-identify their dscp in PacketOptions.
3058 const uint8_t kData[10] = {0};
3059 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003060 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003061
nisse51542be2016-02-12 02:27:06 -08003062 // Verify that setting the option to false resets the
3063 // DiffServCodePoint.
3064 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003065 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3066 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3067 webrtc::CryptoOptions())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003068 channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08003069 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3070 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3071
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07003072 channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003073}
3074
solenberg4bac9c52015-10-09 02:32:53 -07003075TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003076 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003077 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003078 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003079 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003080 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003081 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3082 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3083 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003084}
3085
solenberg2100c0b2017-03-01 11:29:29 -08003086TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003087 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003088
3089 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003090 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003091 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3092
3093 // Should remember the volume "2" which will be set on new unsignaled streams,
3094 // and also set the gain to 2 on existing unsignaled streams.
3095 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3096 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3097
3098 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3099 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3100 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3101 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3102 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3103 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3104
3105 // Setting gain with SSRC=0 should affect all unsignaled streams.
3106 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003107 if (kMaxUnsignaledRecvStreams > 1) {
3108 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3109 }
solenberg2100c0b2017-03-01 11:29:29 -08003110 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3111
3112 // Setting gain on an individual stream affects only that.
3113 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003114 if (kMaxUnsignaledRecvStreams > 1) {
3115 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3116 }
solenberg2100c0b2017-03-01 11:29:29 -08003117 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003118}
3119
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003120TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3121 EXPECT_TRUE(SetupChannel());
3122 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3123 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3124
3125 cricket::StreamParams stream;
3126 stream.ssrcs.push_back(kSsrcY);
3127 EXPECT_TRUE(channel_->AddRecvStream(stream));
3128 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3129 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3130 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3131}
3132
3133TEST_F(WebRtcVoiceEngineTestFake,
3134 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3135 // Here base minimum delay is abbreviated to delay in comments for shortness.
3136 EXPECT_TRUE(SetupChannel());
3137
3138 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3139 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3140 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3141 // Check that it doesn't provide default values for unknown ssrc.
3142 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3143
3144 // Check that default value for unsignaled streams is 0.
3145 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3146
3147 // Should remember the delay 100 which will be set on new unsignaled streams,
3148 // and also set the delay to 100 on existing unsignaled streams.
3149 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3150 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3151 // Check that it doesn't provide default values for unknown ssrc.
3152 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3153
3154 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3155 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3156 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3157 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3158 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3159 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3160
3161 // Setting delay with SSRC=0 should affect all unsignaled streams.
3162 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3163 if (kMaxUnsignaledRecvStreams > 1) {
3164 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3165 }
3166 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3167
3168 // Setting delay on an individual stream affects only that.
3169 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3170 if (kMaxUnsignaledRecvStreams > 1) {
3171 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3172 }
3173 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3174 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3175 // Check that it doesn't provide default values for unknown ssrc.
3176 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3177}
3178
Seth Hampson845e8782018-03-02 11:34:10 -08003179TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003180 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003181 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003182
solenbergff976312016-03-30 23:28:51 -07003183 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003184 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003185 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003186 // Creating two channels to make sure that sync label is set properly for both
3187 // the default voice channel and following ones.
3188 EXPECT_TRUE(channel_->AddRecvStream(sp));
3189 sp.ssrcs[0] += 1;
3190 EXPECT_TRUE(channel_->AddRecvStream(sp));
3191
Mirko Bonadeif859e552018-05-30 15:31:29 +02003192 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003193 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003194 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003195 << "SyncGroup should be set based on stream id";
3196 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003197 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003198 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003199}
3200
solenberg3a941542015-11-16 07:34:50 -08003201// TODO(solenberg): Remove, once recv streams are configured through Call.
3202// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003203TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003204 // Test that setting the header extensions results in the expected state
3205 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003206 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003207 ssrcs.push_back(223);
3208 ssrcs.push_back(224);
3209
solenbergff976312016-03-30 23:28:51 -07003210 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003211 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003212 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003213 EXPECT_TRUE(
3214 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003215 }
3216
Mirko Bonadeif859e552018-05-30 15:31:29 +02003217 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003218 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003219 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003220 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003221 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222 }
3223
3224 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003225 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003226 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003227 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003228 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003229 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003230 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003231 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003232 EXPECT_NE(nullptr, s);
3233 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003234 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3235 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003236 for (const auto& s_ext : s_exts) {
3237 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003238 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003239 }
3240 }
3241 }
3242 }
3243
3244 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003245 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003246 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003247 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003248 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003249 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003250 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003251}
3252
3253TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3254 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003255 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003256 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003257 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003258 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3259 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003261 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003262
solenbergff976312016-03-30 23:28:51 -07003263 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003264 cricket::WebRtcVoiceMediaChannel* media_channel =
3265 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003266 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003267 EXPECT_TRUE(media_channel->AddRecvStream(
3268 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3269
Mirko Bonadeif859e552018-05-30 15:31:29 +02003270 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003272 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003274 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003275 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003276 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003277 EXPECT_EQ(2, 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}